S3

S3の概要

AWSは3つの形式のストレージサービスを提供

◾️ブロックストレージ  ・EC2にアタッチして活用するディスクサービス  ・ブロック形式でデータを保存  ・高速、広帯域幅  ・例:EBS、インスタンスストア

◾️オブジェクトストレージ  ・安価かつ高い耐久性を持つオンラインストレージ  ・オブジェクト形式でデータを保存  ・例:S3、Glacier

◾️ファイルストレージ  ・複数のEC2インスタンスから同時にアタッチ可能な共有ストレージサービス  ・ファイル形式でデータを保存  ・例:EFS

Simple Storage Service(S3)

ユーザーがデータを容量制限なく保存可能なマネージド型で提供されるオブジェクト型ストレージ

【特徴】 ・高い耐久性  99.999999999%

・安価なストレージ  容量単価:月額1GB / 約3円

・スケーラブルで安定した性能  データは冗長化されて保存されデータ容量に依存しない性能がAWS側で保証される

・暗号化  転送中や保存時にデータを暗号化可能

【データ保存形式】 ・バケット  オブジェクトの保存場所  名前はグローバルでユニークな必要あり

・オブジェクト  S3に格納されるファイルでURLが付与される  バケット内オブジェクト数は無制限

・データサイズ  データサイズは0KBから5TBまで保存可能

S3のオブジェクト構成

・Key  オブジェクトの名前であり、バケット内のオブジェクトは一意に識別する

Value  データそのものであり、バイト値で構成される

・バージョンID  バージョン管理に用いるID

メタデータ  オブジェクトに付随する属性の情報

・サブリソース  バケット構成情報を保存および管理するためのサポートを提供  例:アクセス制御リスト(ACL

S3 Inteligent-Tiering

低頻度アクセスのオブジェクトを自動的に低頻度アクセス層に移動することでコストを削減する

S3の値段

保存データ容量、データ取得リクエストおよびデータ転送アウトに応じて課金される

◾️容量当たりの料金  ・最初の50TB / 月 0.025USD / GB  ・次の450TB / 月 0.024USD / GB  ・500TB / 月以上 0.023USD / GB

◾️データ取り出しリクエスト料金  PUT、COPY、POST、LISTリクエスト(1,000リクエスト当たり):0.0047USD  GET、SELECT、他の全てのリクエスト(1,000リクエスト当たり):0.00037USD

◾️データ転送料金 データ転送(イン)は無料 インターネットへのデータ転送(アウト)は以下の通り 1GBまで / 月 0.00USD / GB 次の9.999TB / 月 0.114USD / GB 次の40TB / 月   0.089USD / GB 次の100TB / 月  0.086USD / GB 150TB / 月より大きい 0.084USD / GB

S3の整合性モデル

S3は高い可用性を実現するため、データ更新・削除には結果整合性モデルを採用 同時書き込みはタイムスタンプ処理を実施

◾️新規登録  ・Consistency Read  ・登録時即時にデータが反映される

◾️更新  ・Eventual Consistency Read  ・更新直後はデータ反映に時間がかかる

◾️削除  ・Eventual Consistency Read  ・削除直後はデータ反映に時間がかかる

S3のアクセス管理

◾️IAMポリシー  ・IAMユーザー / サービスに対してS3サービスへのアクセス権限を設定することができる  ・一元的にユーザへのアクセス権限を管理

◾️バケットポリシー  ・バケットへのアクセス権をJSONで設定  ・他アカウントへの許可も可能  ・バケット単位の高度なアクセス管理向け

◾️ACL  ・バケットと個々のオブジェクトへのアクセス権限をXMLで設定する  ・他アカウントへの許可も可能  ・簡易的にアクセス管理向け

◾️著名付きURL  ・AWS SDKで生成した著名付きURLでS3のオブジェクトへの一定時間アクセスを許可

S3の暗号化

◾️SSE-S3  ・S3の標準暗号化方式で簡易に利用可能  ・暗号化キーの作成、管理をS3側で自動で実施  ・ブロック暗号の1つである256ビットのAdvanced Encryption Standard(AES-256)を使用してデータを暗号化

◾️SSE-KMS  ・AWS KMSに設定した暗号化キーを利用した暗号化を実施  ・ユーザ側でAWS KMSを利用して暗号化キーを作成、管理することが可能  ・クライアント独自の暗号キーを利用可能

◾️SSE-C  ・ユーザーが指定したキーによるサーバー側の暗号化(SSE-C)を使用することが可能  ・利用設定や管理が煩雑になるのがデメリット

◾️クライアントサイド暗号化(CSE)  ・クライアント側の暗号化では、AmazonS3に送信する前にデータを暗号化する方式  ・AWS KMSなどを利用して暗号化キーを作成、実施  ・アプリケーション内に保存したマスターキーを使用

VPC

VPCの概要

Virtual Private Cloud(VPCVPCAWSクラウド内に論理的に分離されたセクションを作り、ユーザーが定義した仮想ネットワークを構築するサービス

・任意のIPアドレス範囲の選択して仮想ネットワークを構築 ・サブネット作成、ルートテーブルやネットワークゲートウェイの設定など仮想ネットワーキング環境を完全に制御可能 ・必要に応じてクラウド内外のネットワーク同士を接続することも可能 ・複数の接続オプションが利用可能

VPCとの接続

Direct Conect

お客様のデータセンターやオフィスを専用線などを介してAWSへプライベートに接続するサービス

◾️メリット ・安価なアウトバウンドトラフィック料金 ・ネットワーク信頼性の向上 ・ネットワーク帯域幅の向上

Direct Connectロケーションに物理的に自社オンプレ環境を接続することでAWS環境との専用線接続を実現する

Direct Connect gateway

同一アカウントに所属する複数リージョンの複数AZから複数リージョンの複数VPCに接続

VPNとDirect Connect

VPNの方が安く素早く利用できるが、信頼性や品質は専用線が勝る

VPCエンドポイント

グローバルIPをもつAWSサービスに対して、VPCないから直接アクセスするための出口

Gateway

サブネットに特殊なルーティングを設定し、VPC内部から直接外のサービスと通信する ◾️特徴 ・アクセス制御:エンドポリシーを設定 ・料金:無料 ・冗長性:AWS側が対応

PrivateLink型

サブネットにエンドポイント用のプライベートIPアドレスを生成し、DNSが名前解決でルーティングする ◾️特徴 ・アクセス制御:セキュリティグループを設定 ・料金:有料 ・冗長性:マルチAZ設計

NATゲートウェイ

プライベートサブネットのリソースがインターネットまたはAWSクラウドと通信が可能になる ◾️特徴 ・AWSによるマネージドNATサービス ・EIPの割り当て可能 ・最大10Gbpsの高パフォーマンス ・ビルトインで冗長化されている高可用性 ・アベイラビリティーゾーン毎に設置する

VPC Flow logs

ネットワークトラフィックを取得しCloudWatchでモニタリングできるようにする機能 ・ネットワークインターフェースを送信元 / 送信先とするトラフィックが対象 ・セキュリティグループとネットワークACLのルールでaccepted / rejectされたトラフィックログを取得 ・キャプチャウィンドウと言われる時間枠(約10分間)で収集、プロセッシング、保存する ・RDS、Redshift、ElasticCache、WorkSpacesのネットワークインタフェーストラフィックも取得可能 ・追加料金はなし

VPCの設定上限

・リージョンあたりのVPCの上限数 5 ・VPC当たりのサブネットの上限数 200 ・AWSアカウント当たりの1リージョン内のElasticIP数 5 ・ルートテーブル当たりのルート上限数 100 ・VPC当たりのセキュリティグループの上限数 500 ・セキュリティグループ当たりのルールの上限数 50

VPCを分割するケース

・アプリケーションによる分割 ・監査のスコープによる分割 ・リスクレベルによる分割 ・本番/ 検証 / 開発フェーズによる分割 ・部署による分割 共通サービスの切り出し

VPC Peering

2つのVPC間でのトラフィックルーティングが可能

・異なるAWSアカウント間のVPC間をピア接続可能 ・一部リージョン間の異なるVPC間のピア接続も可能 ・単一障害点や帯域幅ボトルネックは存在しない

EC2

EC2の概要

数分で利用可能となる従量課金で利用可能な仮想サーバー

・起動、ノード追加、削除、マシンスペック変更が数分で可能 ・汎用的なIntelアーキテクチャを採用 ・管理者権限で利用可能 ・WindowsLinuxなどのほとんどのOSをサポート ・OSまでは提供されているタイプを選択することで自動設定され、OSより上のレイヤーを自由に利用可能 ・独自のAmazon Machine ImageにOS設定を作成し、保存して再利用が可能

EC2とは

利用する単位をインスタンスと呼び、任意のAZにインスタンスを立ち上げてサーバーとして利用する

①利用するAMIイメージ(OSセッティング)を選択 ②インスタンスタイプを選択 ③ストレージを選択 ④セキュリティグループを選択 ⑤SSHキーペアを設定

AMIイメージ

OSセッティング方式を選択すること

リサーブドインスタンス

利用期間を長期指定して利用する形式で、オンデマンドに比較して最大75%割安になる

スポットインスタンス

予備のコンピューティング容量を、オンデマンドインスタンスに比べて割引(最大90%引き)で利用できるEC2インスタンス

・予備用を入札式で利用するためとても安い(最大90%引き) ・起動に通常よりも少し時間がかかる ・予備用のため途中で削除される可能性がある  →一時的な拡張などの用途で利用

Saving Plan

1〜3年の期間に一定の使用量を守ることによりAmazon EC2コストを削減する

リザーブインスタンスと同様に、1年または3年の期間に特定の量の処理能力(USD/時間で測定)を使用する契約を結ぶことで適用される割引契約 ・AWSコンピューティング使用料金を最大72%節約できる ・Amazon EC2AWS Fargate、AWS Lambdaに適用可能

キャパシティーの予約

特定のアベイラビリティーゾーンのEC2インスタンスに対して任意の期間キャパシティーを予約する

物理対応可能なインスタンス

物理サーバーにインスタンスを起動して制御が可能なタイプのインスタンス

・ハードウェア専有インスタンス  専用HWのVPCで実行されるEC2インスタンス  ホストHWにレベルで、他のAWSアカウントに属するインスタンスから物理的に分離する  同じAWSアカウントのインスタンスとはHWを共有する可能性がある

・Dedicated Host  EC2インスタンス容量を完全に利用できる物理サーバー

・Bare Metal  アプリケーションが基盤となるサーバーのプロセッサーとメモリーに直接アクセス可能なインスタンス  AWSの各種サービスとの連携が可能でOSが直接下層のハードウェアにアクセス権限

ストレージ

EC2で直接利用するストレージは不可分なインスタンスストアと自分で設定するEBSの2つ

インスタンスストア  ・ホストコンピュータに内蔵されたディスクでEC2と不可分のブロックレベルの物理ストレージ  ・EC2の一時的なデータが保持され、EC2の停止、終了と共にクリアされる

Elastic Block Store(EBS)  ・ネットワークで接続されたブロックレベルのストレージでEC2とは独立して管理される  ・EC2をTerminateしてもEBSは保持可能で、SnapshotをS3に保持可能  ・別途EBS料金が必要

セキュリティグループ

インスタンスへのトラフィックのアクセス可否を設定するファイアーウォール機能を提供

キーペア

キーペアを利用して自身がダウンロードした秘密鍵とマッチした公開鍵を有するインスタンスにアクセスする

EC2のバックアップ

EC2インスタンスは定期的にバックアップすることが重要

・定期的にバックアップを取る ・定期的にリカバリプロセスを確認する ・複数のAZに重要なアプリケーションをデプロイすること ・ファイルオーバー対応を準備すること ・イベントをモニタリングして対応できるようにすること ・インスタンス起動時に動的IPアドレス処理の設定を行うこと

EBSの概要

EC2にアタッチされるブロックレベルのストレージサービス

◾️基本 ・OSやアプリケーション、データの置き場所など様々な用途で利用される ・実態はネットワーク接続型ストレージ ・99.999%の可用性 ・サイズは1GB〜16TB ・サイズと利用期間で課金

◾️特徴 ・ボリュームデータはAZ内で複数のHWにデフォルトでレプリケートされており、冗長化不要 ・セキュリティグループによる通信制御対象外であり、全ポートを閉じてもEBSは利用可能 ・データは永続的に保存 ・EC2インスタンスは他のAZ内のEBSにはアクセスできない ・EC2インスタンスに複数のEBSを接続することはできるが、EBSを複数のインスタンスで共有することはできない ・同じAZ内のインスタンスに付け替えできる

Snapshot

EBSはスナップショットを利用してバックアップを取得する

◾️特徴 ・Snapshotでバックアップ ・SnapshotからのEBSを復元する際は別AZにも可能 ・SnapshotはS3に保存される ・Snapshotの2世代目以降は増分データを保存する増分バックアップとなる(1世代目を削除しても復元は可能) ・Snapshot作成時にブロックレベルで圧縮して保管するため、圧縮後の容量に対して課金が行われる

スナップショットはリージョン間をまたいで利用可能 Snapshot作成時はデータ整合性を保つため静止点の設定を推奨

◾️Snapshot作成時はデータ整合性を保つため静止点の設定を推奨 ・ソフトウェアの機能を利用 ・ファイルシステムの機能を利用 ・バックアップソフトウェアの機能を利用 ・アプリケーションの停止 ・ファイルシステムのアンマウントなど

◾️保存期間や世代数は無制限 ◾️世代管理が必要な場合はAWS CLIAPI等で自動化する

スナップショットとAMI Amazon Machine ImageはOS設定のイメージであり、Snapshotはストレージのバックアップとなる

◾️AMI ・ECインスタンスのOS設定などをイメージとして保持して新規インスタンス設定に転用するもの

◾️Snapshot ・ストレージ / EBSのその時点の断面のバックアップとして保持するもの ・ストレージの復元や複製に利用

EBSのボリュームタイプ

ユースケースに応じて性能やコストが異なる5種類のボリュームタイプから選択

◾️SSD ・汎用SSD  →仮想デスクトップ  →低レイテンシーを要求するアプリ  →小〜中規模のデータベース  →開発環境

・プロビジョンドIOPS  →高いI/O性能に依存するNoSQLやアプリ  →10,000IOPSや160MB / s超のワークロード  →大規模DB

◾️HDD ・スループット最適化HDD  →ビックデータ処理  →DWH  →大規模なETL処理やログ分析

・コールドHDD  →ログデータなどアクセス頻度が低いデータ  →バックアップやアーカイブ

◾️マグネティック(Magnetic)  →旧世代のボリュームで基本利用しない  →データへのアクセス頻度が低いロークロード

インスタンスストア

EC2が利用するのはインスタンスストアとEBSの2タイプのストレージ

◾️インスタンスストア ・ホストコンピュータに内蔵されたディスクでEC2と不可分のブロックレベルの物理ストレージ ・EC2の一時的なデータが保持され、EC2の停止、終了とともにデータがクリアされる ・無料

◾️Elastic Block Store(EBS) ・ネットワークで接続されたブロックレベルのストレージでEC2とは独立管理 ・EC2で終了してもEBSデータは保持可能 ・SnapshotをS3に保持可能 ・別途EBS料金が必要

IAM

AWSの仕組み

・アンマネージド型  スケーリング / 耐障害性 / 可用性を利用者側で設定し、管理する必要がある  メリット:設置が柔軟に可能  デメリット:管理が面倒

・マネージド型  スケーリング / 耐障害性 / 可用性がサービスに組み込まれており、AWS側で管理される  メリット:管理が楽  デメリット;設定が限定的

IAM

概要

セキュリティに対してAWSとユーザーとで責任分界して対応する(責任共有モデル)

ユーザー側の責任範囲 ・IAMによるアカウント管理 ・セキュリティグループの設定 ・アプリケーションのロールベースのアクセス設定 ・ネットワーク / インスタンスオペレーションシステム(バッチ)などの設定 ・OS / ホストベースのファイアーウォール設置

IAMとは

AWS Identity and Access Management(IAM)は安全にAWS操作を実施するための認証・認可の仕組み →アクセス権限をどう管理するか・どう与えるかなどのアクセス権限全般の管理をする認証などの仕組み

AWS利用者認証の実施 ・アクセスポリシーの設定 ・ユーザー個人またはグループ設定

ユーザー

ルートユーザー

最初に作成されるのがルートユーザー。 普段はあまり使わない。

AWSルートアカウントのメールアドレスやパスワード変更 ・IMAユーザーの課金情報へのアクセスに関するactivate / deactivate ・他のAWSアカウントへのRoute53のドメイン登録の移行 ・CloudFrontのキーペア作成 ・AWSサービス(サポート等)のキャンセル ・AWSアカウントの停止 ・コンソリデイテッドビリングの設定 ・脆弱性診断フォームの提出 ・逆引きDNS申請

IAMユーザー

IAMポリシー内でAWSサービスを利用できるユーザー。 基本操作はIAMユーザーで実施することになる。

設定上限 1アカウントで5000ユーザーまで作成可能

設計内容 ユーザー名 パス(オプション)  ユーザーにオプションとして設定できる情報であり、パスを元にユーザーの検索が可能となる。  組織階層やプロジェクトなどを設定できる。

所属グループ  10のグループまで設定可能。

パーミッション  AWSサービスへのアクセス権限

IAMグループ

設定上限 1アカウントで300グループまで作成可能

設計内容 グループ名

パス(オプション) 組織階層などをセット

パーミッション グループに設定したパーミッションはIAMユーザーに付与したパーミッションと同時に評価する。

IAMポリシー

IAMポリシーを作成してユーザーなどへのアクセス権限を付与(JSON形式)

・管理ポリシー AWS管理ポリシー  AWSが作成および管理する管理ポリシー

カスタマー管理ポリシー  AWSアカウントで作成、管理する管理ポリシー。  同じポリシーを複数のIAMエンティティにアタッチできる。

・インラインポリシー 自身で作成および管理するポリシー  1つのプリンシパルエンティティ(ユーザー、グループ、またはロール)に埋め込まれた固有ポリシーで、プリンシパルエンティティにアタッチすることができる。

IAM設計

AWSを利用するユーザーの役割やアクセス権限を自社の組織構造と合わせて設計することが重要。

ベストプラクティス

1、アカウント設定などの重要な場合を除いて、ルートユーザーを利用しない 2、ルートユーザーなどの特権ユーザーに対して、MFAを有効化する 3、利用者ごとにIAMユーザーを作成する 4、組織利用の場合は、役割ごとのIAMグループを作成してグループで管理するのを基本とする 5、最小限の権限設定と不要な認証情報は削除を心がける 6、ユーザーのために強度の高いパスワードポリシーを設定する 7、EC2インスタンスで作動するアプリケーションなどプログラムから利用する場合はなるべくロールを使用する 8、モバイルやアプリケーションも含め、一時利用にはSTSなどで最小限の利用許可を与える 9、AWSアカウントのアクティビティを常に監視する

AWS Organizations

IAMのアクセス管理を大きな組織でも楽に実施できるようにするマネージド型サービス

複数アカウントの一元管理 ・新規アカウント作成の自動化 ・一括請求

組織という単位を構成して、マスターアカウントがメンバーアカウントを管理するという仕組み

機能セットの選択

支払い一括代行とアカウントの全体管理 ・Consolidated Billing Only  →支払一括代行のみを実施する場合に選択 ・All Feature  →支払一括代行も含めて、企業内の複数アカウントを統制したい場合に選択

マスターアカウントの設定

AWSアカウントの中からマスターアカウントを選定する

Go 構文

Hello world

package main

import "fmt"

// 最初に呼び出される
func init() {
    fmt.Println("Init!")
}

func bazz() {
    fmt.Println("Bazz")
}

// 2番目に呼び出される
func main() {
    // bazz()
    fmt.Println("Hello world!", "TEST TEST")
}

パッケージ(import)

package main

import (
    "fmt"
    "os/user"
    "time"
)

func main() {
    fmt.Println("Hello world!", time.Now())
    fmt.Println(user.Current())
}

変数宣言

var

package main

import "fmt"

var (
    i    int     = 1
    f64  float64 = 1.2
    s    string  = "test"
    t, f bool    = true, false
)

func foo() {
    // :=は関数の中でしか使用できない
    xi := 1
    xi = 2
    xf64 := 1.2
    var xf32 float32 = 1.2
    xs := "test"
    xt, xf := true, false
    fmt.Println(xi, xf64, xf32, xs, xt, xf)

    // Printfの"%T"で型を調べて出力することができる
    fmt.Printf("%T\n", xf32)
    fmt.Printf("%T\n", xi)
}

func main() {
    fmt.Println(i, f64, s, t, f)
    foo()
}

for文

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        if i == 3 {
            fmt.Println("continue")
            continue
        }

        if i > 5 {
            fmt.Println("break")
            break
        }
        fmt.Println(i)
    }

    sum := 1
    for sum < 10 {
        sum += sum
        fmt.Println(sum)
    }
    fmt.Println(sum)
}

defere

package main

import "fmt"

func foo() {
    defer fmt.Println("world foo")

    fmt.Println("hello foo")
}

func main() {
    /*
       foo()
       defer fmt.Println("world")

       fmt.Println("hello")
   */

    fmt.Println("run")
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
    fmt.Println("success")
}
run
success
3
2
1

スライス

func main() {
    n := []int{1, 2, 3, 4, 5, 6}
    fmt.Println(n)      // [1 2 3 4 5 6]
    fmt.Println(n[2])   // 3
    fmt.Println(n[2:4]) // [3 4]
    fmt.Println(n[:2])  // [1 2]
    fmt.Println(n[2:])  // [3 4 5 6]
    fmt.Println(n[:])   // [1 2 3 4 5 6]

    n[2] = 100
    fmt.Println(n) // [ 1 2 100 4 5 6]

    var board = [][]int{
        []int{0, 1, 2},
        []int{3, 4, 5},
        []int{6, 7, 8},
    }
    fmt.Println(board) // [[0 1 2] [3 4 5] [6 7  8]]

    n = append(n, 100, 200, 300, 400)
    fmt.Println(n) // [1 2 100 4 5 6 100 200 300 400]
}

make

func main() {
    // makeで初期化 make(型type, 長さlen, 容量cap)
    n := make([]int, 3, 5)
    fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) // len=3 cap=5 value=[0 0 0]
    n = append(n, 0, 0)
    fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) // len=5 cap=5 value=[0 0 0 0 0]

    // スライスのため追加できる
    n = append(n, 1, 2, 3, 4, 5)
    fmt.Printf("len=%d cap=%d value=%v\n", len(n), cap(n), n) // len=10 cap=10 value=[0 0 0 0 0 1 2 3 4 5]

    // 引数を一つにすると長さも容量も同じになる
    a := make([]int, 3)
    fmt.Printf("len=%d cap=%d value=%v\n", len(a), cap(a), a) // len=3 cap=3 value=[0 0 0]

    // 0のスライスをメモリに確保する
    b := make([]int, 0)
    // メモリに確保しない
    var c []int
    fmt.Printf("len=%d cap=%d value=%v\n", len(b), cap(b), b) // len=0 cap=0 value=[]
    fmt.Printf("len=%d cap=%d value=%v\n", len(c), cap(c), c) // len=0 cap=0 value=[]

    c = make([]int, 5)
    for i := 0; i < 5; i++ {
        c = append(c, i)
        fmt.Println(c) // [0] [0 0] [0 0 0] [0 0 0 0] [0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0 1] [0 0 0 0 0 0 1 2] [0 0 0 0 0 0 1 2 3] [0 0 0 0 0 0 1 2 3 4]
    }
    fmt.Println(c) // [0 0 0 0 0 0 1 2 3 4]

    var d []int
    d = make([]int, 0, 5)
    for i := 0; i < 5; i++ {
        d = append(d, i)
        fmt.Println(d) // [0] [0 1] [0 1 2] [0 1 2 3] [0 1 2 3 4]
    }
    fmt.Println(d) // [0 1 2 3 4]
}

map

func main() {
    m := map[string]int{"apple": 100, "banana": 200}
    fmt.Println(m)          // map[apple:100 banana:200]
    fmt.Println(m["apple"]) // 100
    m["banana"] = 300
    fmt.Println(m) // map[apple:100 banana:300]
    // 新しい要素を追加
    m["new"] = 500
    fmt.Println(m) // map[apple:100 banana:300 new:500]

    // 存在しない値を取り出すと
    fmt.Println(m["nothing"]) // 0

    // 値の確認
    v, ok := m["apple"]
    fmt.Println(v, ok) // 100 true

    // 存在しない値を確認すると
    v2, ok2 := m["nothing"]
    fmt.Println(v2, ok2) // 0 false

    // mapは返り値を無視することができる
    v := m["apple"]
    fmt.Println(v) // 100 true

    // keyがstring、valueがintのmapを初期化
    // メモリ上に空のマップを作成
    m2 := make(map[string]int)
    m2["pc"] = 5000
    fmt.Println(m2) // map[pc:5000]

    // メモリ上に入れるマップがないためpanicになる
    // マップを初期化していない状態(nil)で値をセットするとpanicになる
    var m3 map[string]int
    m3["pc"] = 5000
    fmt.Println(m3) // panic: assignment to entry in nil map

    // varで宣言した場合はnilになる(スライスでもマップの場合でも)
    var s []int
    if s == nil {
        fmt.Println("Nil") // Nil
    }
}

関数

func add(x, y int) (int, int) {
    return x + y, x - y
}

func cal(price, item int) (result int) {
    result = price * item
    return
}

func main() {
    r1, r2 := add(10, 20)
    fmt.Println(r1, r2) // 30 -10

    r3 := cal(100, 2)
    fmt.Println(r3) // 200

    f := func(x int) {
        fmt.Println("inner func", 1)
    }
    f(1) // inner func 1

    // 省略記法
    func(x int) {
        fmt.Println("inner func", 1)
    }(1) // inner func 1
}

ポインタ

package main

import "fmt"

func main() {
  var p *int

  fmt.Println(p == nil)  // true 定義のみを行ったポインタ型の変数の初期値はnilになり、参照型と同じ様に振る舞う
}

func Double(i int) {
  i = i  * 2
}

func main() {
  var n int = 100

  Double(n)

  fmt.Println(n) // 100
}
0xc000b4008番地 100 変数n(実引数)

↓値渡しでは変数の値をコピーする

0x999b11111番地 100 変数i(仮引数)

↓この後Double関数が実行され、変数iの値が変更される

0x999b11111番地 200 変数i

↓値渡しのため変数nには反映されない(仮引数を変更しても、実引数には反映されない)

fmt.Println(n) // 100
package main

import "fmt"

func main() {
  var p *int

  fmt.Println(p == nil)  // true 定義のみを行ったポインタ型の変数の初期値はnilになり、参照型と同じ様に振る舞う
}

json

import "encoding/json"

encoding/jsonパッケージはRFC4627に準拠したJSONエンコーディングを処理するエンコーダーデコーダーの機能を提供

構造体型からJSONテキストへの変換

関数json.Marshalは、任意の構造体型からJSONテキストへのエンコード処理を実行する 内部的にreflectパッケージのリフレクション機能が使用されており、特別な設定をせずとも構造体型に定義されたフィールド名と値の組み合わせから自動的にJSONテキストを生成する

json.Marshalの戻り値は[]byte型のため、テキストとして確認する場合はstring(bs)のように文字列へ変換する必要がある また、出力されるJSONテキストのキーを構造体フィールド名ではなく、任意の名前にマッピングしたい場合は構造体の「タグ」を利用できる

gorilla/mux

func getArticle(w http.ResponseWriter, r *http.Request) {
        // Vars関数でパラメータの値を取得
    // get http://localhost:8000/articles/1 -> 1を取得
    params := mux.Vars(r)
    fmt.Println(params) // map[id:1]

        // reflect 動的に型を扱いたい場合に便利なパッケージ
        // typeof 型確認
    fmt.Println(reflect.TypeOf(params["id"])) // string

    // Convert Type from String -> Int
    // Not handling err -> _
    i, _ := strconv.Atoi(params["id"])

    // URLに指定したIDの情報を取得
    for _, article := range articles {
        if article.ID == i {
            json.NewEncoder(w).Encode(&article)
        }
    }
}

サーバサイド Go 入門資料 まとめ · GitHub

future-architect.github.iofuture-architect.github.io

Linuxディレクトリ構造

/bin  OSが正常に動作するための実行ファイル(コマンドを実行するためのファイルが入っている、ls・cpコマンドなど)

/boot システムの起動に必要なファイル(あまりいじることはないはず)

/dev  ハードウェア機器を表すファイル

/etc  設定ファイル

/home ユーザーのホームディレクト

/lib   OSに必要なライブラリファイル

/media 外部の記憶媒体をマウント(システムが自動でマウントする場合)

/mnt  同上(ユーザーが自動でマウントする場合)

/opt 追加のアプリケーションがインストール(第三者サードパーティアプリをインストールする場所、Chromeなど)

/proc OSのシステムをコントロール

/root rootアカウントのホームディレクト

/sbin ルートユーザーのみ実行できるプログラム

/sys OSの現在の状況に関する情報

/usr 全ユーザーが共通して利用するプログラムのデータ

/var システム運用中に生成、後から削除されるデータ

 

$ touch 

(ファイル作成)

$ chmod u+rw-x,go+r-wx chownfile

(ファイルモードを「rw-r--r--」に変更)

$ ls -l chownfile

-rw-r--r-- 1 penguin linuc chownfile

 

$ chmod g+w chownfile

(グループにw(書き込み権限)を追加)

$ ls -l chownfile

-rw-rw-r-- 1 penguin linuc

 

$ chmod u-r,o+w chownfile

(ユーザーからr(読み込み権限)を削除、その他にw(書き込み権限)を追加)

$ ls -l chownfile

--w-rw-rw- 1 penguin linuc

 

 

Linuxディレクトリ構造

/bin  OSが正常に動作するための実行ファイル(コマンドを実行するためのファイルが入っている、ls・cpコマンドなど)

/boot システムの起動に必要なファイル(あまりいじることはないはず)

/dev  ハードウェア機器を表すファイル

/etc  設定ファイル

/home ユーザーのホームディレクト

/lib   OSに必要なライブラリファイル

/media 外部の記憶媒体をマウント(システムが自動でマウントする場合)

/mnt  同上(ユーザーが自動でマウントする場合)

/opt 追加のアプリケーションがインストール(第三者サードパーティアプリをインストールする場所、Chromeなど)

/proc OSのシステムをコントロール

/root rootアカウントのホームディレクト

/sbin ルートユーザーのみ実行できるプログラム

/sys OSの現在の状況に関する情報

/usr 全ユーザーが共通して利用するプログラムのデータ

/var システム運用中に生成、後から削除されるデータ