給料の交渉についての怪文章

「交渉すると給料が上がる」「給料は交渉すべき」と言った話をたまに聞くが、給料の交渉が嫌いなので考えてみた。 これは真面目な考察ではなく、自分の感情に対する整理のための怪文章である。

特に後半は完全な怪文章となっている。

交渉しなくても上がる組織にいた

新卒で入社した会社に4年くらい在籍していたが、結構どんどん給料が上がる会社だったと思っている。 実質給与改定の時期というものはなく(本当はあったのかもしれない)、1年の中でも勝手にどんどん上がる組織だった。

これにはいくつか理由があると思っていて、なんとなく思いつくのは

  • 組織の人数が少ない(20人くらい)
  • 受託開発だった

あたりだろうか。

組織の人数が少ないとなぜ給料が上がりやすいと思うのか

まず単純に、「評価」という点においてマイクロマネジメントがしやすいからじゃないかと思う。

特に、「給料をあげる」権限を持っている人の人数に対して、「給料をあげられる側」の人数が少ないため、「給料をあげる」権限を持っている人が「こいついいじゃん」と思ったら給料が上がるのである。

組織の規模が上がると、「給料をあげる」権限を持っている人と、「給料をあげられる側」の距離が遠くなるのではないか。

「給料をあげられる側」には多分上司がいて、上司がその人の評価をするのだが、上司が「給料をあげる権限」を持っておらず、さらに上司の上司も「給料をあげる権限」を持っていなかったりすると、直属の上司が「あいつ良い」という話をしても「給料をあげる権限」を持っている人の心に響かなければ給料は上がらない。

さらにそれが上司から上司に向かってどんどん伝言ゲームが続くことによって、最悪直属の上司の「あいつ良いです」が途中で消滅し、「給料をあげる権限」を持っている人まで届かない可能性がある。

この場合、当然給料は上がらない。なぜなら、「給料をあげる権限」を持っている人は「あいつが良い」ということを知らないからだ。

交渉によって給料が上がる、というケースにはこの「伝言ゲームによって消滅した{あいつ良いです}を無理やり{給料をあげる権限}を持っている人に届かせる」働きがあると思う。 給料の交渉の場には、おそらく「給料をあげる権限」を持っている人がいる可能性が高いからだ。

話がそれるが、自分がメインでやっているタスク以外によく絡む人(球拾いをする人)の給料が上がりやすいという話をきく。 これは、「球拾いがえらい」からではなく

  • 給料をあげる権限を持った人の視界に入る可能性が高い
  • 伝言ゲームの数そのものが増える(いろんな人から「あいつは良い」が発信される)ことで、給料をあげる権限を持った人まで届く可能性が上がる

からなのではないか。

えらいのは球拾いをすることではなく組織の目標に近づけた量が大きい人だと思うが、組織の目標に近づけた量の正確な計算は限りなく難しい。

ただし、よく球拾いをしている人ってそもそも能力高いこと多いなーっていう気もする。タスクを振るひとの想像よりもタスクをこなすスピードが早くて、その隙間の時間で球拾いをしているのでしょうか。

受託開発だった

多分どの組織もトータルでの利益や売り上げの計算はできるが、誰の影響が何割ずつ利益に影響があったのか?はかなり計算が難しいと思う。

特に、何かサービスを提供するビジネスモデルでは、正確な計算はほとんど不可能に近い。

しかし、私は受託開発をメインとする会社で働いていたため、少なくとも「チーム」で「どれくらいの売り上げが出ているか」はかなり正確な値が計算できた。

チームの中で各自がどれくらいの売り上げが出ていたか?についてはどのような評価基準があったのかわからないが、チームの規模は小規模(3〜5人くらい)だったので、印象に対する結果の精度もある程度出ていたのではないかと思う。

また、チームリーダーになって以降おそらく評価の基準は「どれだけ利益をあげたか」だったので、私に対する評価の計算は簡単だったのではないだろうか。

給料の交渉が嫌い

なんで嫌いなのか、については

  • そもそも金の話をするのが美しくないという風潮がある
  • 自分のタスクが金額に換算するとどうなるのか自分でわからない
  • 交渉によって給料が上がっても不愉快

あたりが思いつくが、おそらく私に関しては「そもそも金の話をするのが美しくないという風潮がある」はあまり関係ない。なぜなら私は金の話をするのが大好きだからだ。金の話ばかりしている気がする。

自分のタスクが金額に換算するとどうなるのか自分でわからない

これは結局「誰の影響が何割ずつ利益に影響があったのか?」が自分でもわからない、という話であり、根拠のない金額の提示をするのが嫌だという話だ。

さらに他人にもおそらく正確な値は出せないので、「交渉相手が出した私の価値に対してのおそらく不正確な想像」と「自分で思っている私の価値に対してのおそらく不正確な想像」を戦わせるのが不毛だと感じるからである。

そして、「交渉相手が出した私の価値に対してのおそらく不正確な想像」と「自分で思っている私の価値に対してのおそらく不正確な想像」がズレていた時におそらく、少なくとも私には大きなストレスがかかることが想像できる。

交渉によって給料が上がっても不愉快

まず、「交渉相手が出した私の価値に対してのおそらく不正確な想像」と「自分で思っている私の価値に対してのおそらく不正確な想像」が「自分が思っているほど自分の価値がないと思われているケース」だが、これはもう確実にストレスがかかる。

これはまあしょうがないと思うんだけど、問題は「交渉によって給料が上がる」ケースだ。

交渉によって給料が上がることによる不快感はざっくりいうと、「100万円の価値があると思っている相手が80万円で働いていても文句を言わないからラッキー」という状況なのでは?と思っているように感じてしまうからだ。

まあこのラッキーをベースにした決定が間違っているかというとそうでもないと思うんだけど、個人的には嫌いだ。

なぜなら大抵の人が金を欲しいと思っている(と、思っている)からだ。

大抵の人が、というところが重要で、そうでないのであればこの考え方は間違っている。給料が増えるというイベントが精神に全く影響を与えない人に対して給料をあげる必要はないと思っているからだ。人類の幸せの総量はあげていくべきである。

このイメージはなぜか「学校の掃除をサボる」という行為に対する感情に似ている(ちなみに、このイメージは間違っていると思っている。個人的な感情の話である)。学校の掃除をサボった人に対してのリスクや罰則はほとんどなかったように思えるが、掃除を真面目にやっていた人たちはおそらく「掃除が好きだから掃除をしていた」訳ではなかったはずだ。(中には一定数そういう人もいたと思うが)

言いたいのは、やりたくないがゆえにやらなかった人を罰せよ、ということではなく、「やりたくないのにやった人」と「やりたくないからやらなかった人」の境遇が同じなのではおかしいのではないか?という感情についてだ。

この感情については理由がまだいまいちしっくりきていない。

結論

ここまで書いて、「交渉」はそこまで間違った行為ではないなとも思えた。

交渉によって評価の精度が上がる可能性があるからだ。

嫌いだという感情は依然として変わらない。

100万円分の仕事をした給料を100万円もらっている人と、100万円分の仕事をした給料50万円の人が混在する状況は気持ちが悪いし、それを埋めるのが「交渉」なのは感情的に嫌いだからである。

個人的には、評価の精度を「交渉した後の結果」と同じくらいまで出せる仕組みを持った組織で働きたい。これは精度の話ではない。

交渉によって給料が上がった実績のある組織は、その仕組みを持っていないか、文句を言わない相手に対して貢献度に比例した給料を払う必要はないという前提で動いている組織である。嫌いだが間違っているとは思わない。

ただし、ストレスなく交渉をできるようになれるのであれば、そのほうが幸せになれるとは感じている。 自分の幸せに向かって組織を変えていったり、そういった組織を1から作る、ということがサクサクできるほどの能力を自分に感じていないからだ。

(動画まとめ)AWS re:Invent 2016: Scaling Your Web Applications with AWS Elastic Beanstalk (DEV206)


AWS re:Invent 2016: Scaling Your Web Applications with AWS Elastic Beanstalk (DEV206)

なぜElastic Beanstalkを作ったのか

  • 複雑なコードのデプロイ、セットアップ、インフラの管理
  • サーバの設定、DB、ロードバランサー、firewall、ネットワークの管理に訓練と時間が必要
  • スケールの自動化をどうするか
  • チーム間の整合性をどう取るか

Elastic Beanstalkって?

  • デプロイ、スケール、Webアプリとサービスの管理を簡単にしてくれる奴

何がいいのか

  • 簡単に始められる
  • 開発者の生産性と速度
  • 不足を感じさせない(スケールできる的な意味?)
  • 完全なリソースの管理
  • 追加コストはない(リソースのコストだけ)

ユースケース

  • Webサイト
  • APIバックエンド
  • モバイルのバックエンド
  • 非同期のワーカー

どう始めるの?

  1. コードがあります
  2. リージョンを選びます
  3. Stack(container) typeを選びます(プラットフォーム)
  4. 1インスタンスか、分散+オートスケールするか
  5. RDS

アプリケーションはデプロイバージョンで管理され、各バージョンが各環境にデプロイできる(dev, tset, prodとか)

どうデプロイするか

  • コンソール
  • IDEのツールキット
  • SDKs,CLI
  • EBコマンド

EBコマンドについて

  • $eb initしたディレクトリ(プロジェクト)でコマンドを叩くとそのバージョンでデプロイできる
    • 修正、デプロイ、修正、デプロイ、みたいな

ebextensions

Option settings

CodeCommitとの連携

新しいバージョンのデプロイ

  • デフォルトだと全インスタンスが一気にバージョン上がる
    • ダウンタイムがある

ローリング

//途中 22:49 https://www.youtube.com/watch?v=Fv0yG_wDgoo

  • underneath
  • agility
  • outgrow
  • intimidate
  • terminology
  • opinionated
  • tailor
  • plumb
  • shrink-wrap
  • simultaneously
  • essentially

(動画まとめ)AWS re:Invent 2015: All You Need To Know About Auto Scaling (CMP201)


AWS re:Invent 2015: All You Need To Know About Auto Scaling (CMP201)

ELB

Auto Scaling group

Lounch Configration

  • どんなサーバを立ち上げるか
    • AMI, instance type, size
    • Security groupsm, SSH keys, IAM instance profile
    • User data
    • etc
  • AZとsubnetを除いたインスタンス立ち上げ時に必要な情報をすべて設定する

Golden image approch

  • Webサーバとかアプリとか設定とか全部作ったAMIを使う
  • 変更しまくるとAMIだらけになる
    • どれがどのバージョンかわかるようにする必要がある
    • OSのバージョンアップとかでもAMIをアップデートする必要がある

おすすめ

  • ベースAMIを作る
    • Webサーバとかログのエージェントとかいれとく
    • のこりはuserDataでやる
      • あとはChefとかpuppetとか
        • CodeDeployも
          • UserDataでcodedeployをインストールする感じ
    • バランスはチームの文化とかツールに依存する

インスタンスをターミネイトする時

  • 猶予期間だけセッションがはけるのをまつ

どのインスタンスたターミネイトされるか

  • Termination Policies
    • 常にAZ間のバランスを保つ
    • その上でどうターミネイトするか

いつスケールされるか

Scaling Plans

  • いつローンチされていつターミネイトするか
  • desired capacityよりローンチ済みのインスタンスが少なければ増えるし、多ければ減る
    • default: ヘルスチェックがこけたインスタンスを潰して新しくローンチ
      • desired capacityは固定
    • Manual scaling:desired capacityをAPIとかコンソールとかで変える
    • Scheduled: スケジュールでやる
    • Dynamic scaling: CloudWatchメトリクスによるスケール

ELBとASGのインテグレーション

  • トラフィックの分散
  • アプリケーションのエンドポイントを1つに
  • Connection drainingで登録解除中のインスタンスにリクエストを送らない
  • ELBのメトリクスでスケール
  • 複数のELBとあわせ動作できる
  • インスタンスの登録と解除をターミネーションとあわせて自動で行う
  • Auto Scaling groupでELBヘルスチェックを使える
  • Scaling policyでELBメトリクスが使える

AutoScalingの利点

  • 需要にあわせて自動でキャパシティを設定
  • 信頼性

可用性と信頼性

  • Health check

Health Checkの種類

  • EC2 instance status: EC2のステータス
  • ELB health check: ELBからのリクエストに対するレスポンスでチェック参考
  • Manual: 自分で定義したヘルスチェック
    • ディスクフルとかいろいろ

## AZごと死んだら * desired capacityを満たすように偏ることもある * AZが生き返るとリバランシングする

## Scaling policies * どのようにキャパシティが変わるか * desired capacityにあわせて * 個数で増減 * 割合で増減

スケジュールによるスケール

動的なスケーリングポリシー

  • 需要によるイベントをスケールのトリガーにする
  • メトリクスで需要を図る

CloudWatch

  • CPUとかネットワークトラフィックとか
  • アラーム = しきい値を指定した時間超えた
    • 指定した時間 = evaluation period
  • 一時的なCPUのスパイクでスケールさせたくない
  • アラームがAuto Scalingに通知してスケールをキックできる
  • 閾値超えからクールダウン終了までは別のアラームやスケールのイベントは起きない

めっちゃスパイクしたら間に合わなくね?

Step Scaling Policies

  • 同じポリシーで段階的なステップを定義できる
  • この段階的なステップでは追加のアラームやスケールが発生する
  • コンソールでも定義できる

warmup period

参考

Lifecycle Hooks

ユースケース

  • EIPのアサイ
  • DNSやらキューやらに登録
  • ターミネイトされる前にログをpull
  • ターミネイトされる前に問題の調査

どう動く?

参考

どうやる?

  • 通知先を作る(SQSかSNS
  • IAM roleを作る(Auto Scaling to access the notification queue/topic)
  • lifecycle hootとAutoScaling group, role ,通知先を連携
  • フックで動くコードを書く

LifecycleActionToken

  • アクションを続けたり破棄したりするのに必要
    • 次のステップにわたしてこれ継続よろみたいな

アクションはどう書く?

  • トークン、インスタンスID,その他パラメータの抽出
  • トークンはとっとく
  • なんかする
  • 終わったらCompleteLifecycleActionを送る
    • もっと時間が欲しければheartbeatを送る

SNSもいける

  • インスタンスがInService, Terminatedになってから送られる
    • Lifecycle hooksはその前の準備中に動く

スタンバイにできる

  • InServiceではない
  • Terminateもされない
  • InServiceに戻せる(API,CLI

ググった単語

  • descend
  • arbitrary
  • spectrum
  • flip side
  • grace period
  • drain
  • get rid of
  • accordance
  • sit on
  • whatever
  • boundaries
  • fleet
  • distribute
  • reliability
  • periodically
  • superfluous
  • counteract
  • use a neat trick
  • anticipate
  • predicable
  • disorient
  • investigate
  • abandon
  • extract
  • forensic

(動画まとめ)AWS Summit Series 2016 | Chicago - DevOps on AWS

AWS Summit Series 2016 | Chicago - DevOps on AWS


AWS Summit Series 2016 | Chicago - DevOps on AWS

ソフトウェアのリリースプロセス

Continuous integration

ソースコードをどこかにコミットして、テストして、ビルドまで。

Continuous delivery

ソースコードをどこかにコミットして、テストして、ビルドして、どこかの環境へのデプロイの準備ができるまで。

Continuous deployment

あらゆるコミットが本番環境に反映されるまで。

Continuous deliveryのメリット

  • 同じことなんかいもするのはだるい
  • コミットごとにテストを動かしてバグを対処したりできる
  • 週末とか夜のビルドをまたなくていい
  • 素早いアップデートの提供

AWS Codepipeline

  • 素早く信頼性のあるアプリケーションのアップデート
  • リリースプロセスの可視化
  • コードの変更ごとにビルド、テスト、デプロイ
  • サードパーティツールとの統合

AWS Codepilelineの要素

  • Pipeline
    • Stageで構成される
  • Stage
    • Actionで構成される
    • Transisionで違うStageとつながる
  • Action
    • 並行/直列実行できる

例の流れ

  1. GitHubにコミット
  2. Pipelineが変更をpullする
  3. S3にartifactsをPUT
  4. 次のステージに遷移しJenkins立ち上がってポーリング
  5. S3からjenkinsがartifactsを取得
  6. Jenkinsがビルド結果をS3にPUT
  7. JenkinsがPipelineに成功を通知
  8. 次のステージへ
  9. ビルド結果を取得
  10. Beanstalkに渡す
  11. Beanstalkがデプロイ

例ではCodepipelineは別ツールへのインターフェース

AWS CodeDeploy

  • どんなインスタンスへも自動でコードをデプロイ
  • 複雑なアップデートのハンドリング
  • ダウンタイムを避けたデプロイ
  • 言語やOSにかかわらずEC2やオンプレにデプロイ
  • サードパーティツールとの統合

appspec.yml

hooksでライフサイクルの定義ができる
起動時キックするスクリプトとかの指定
 → ELBに登録したりとか

ダウンタイム無しでのデプロイ

  • One at time
  • half at time
  • all at one

Lambdaによるアクション

  • 5分では処理できないタスクはContinuation Tokenで

わかりやすいJavaEEウェブシステム入門でいきなりハマった(macOS Sierra)

p17で最初のプロジェクトを実行したところでデプロイに失敗しハマる
具体的には以下のような状況

以下のページにてmacOS Sierraだとあかんとかなんとか
mac os Sierra でのGlassfish起動

記載の手順に従って、

  1. mac側のシステム環境設定→ネットワーク→詳細→プロキシ→自動プロキシ検出にチェック
  2. NetBeansNetBeans→Preference→「システムのプロキシ設定を使用」の隣にある「再ロード」クリック+その下の「接続のテスト」をクリック で、とりあえず起動できた。

アキネーターの作品版を作ったら金になるのではないかと思った

要件のイメージ(漫画版を仮定)

  • 〜な(抽象的な希望)漫画を探している、といった人がターゲット
  • 漫画喫茶に来たけどいまいち読みたい漫画がない人とか
  • 現実っぽいやつ or ファンタジーっぽいやつ、みたいな選択肢がでてくる
  • 選択肢はだんだん具体的になる(職業モノ or 趣味モノ、とか、人が死ぬかどうか?とか)
  • 最終的に選ばれた作品のAmazonへのリンクが出てきてアフェリエイトで稼ぐイメージ(音楽版だったらYoutubeとか、アフェリエイトあるのか知らんけど)

問題

  • 初期のデータをどう集めるか
  • 初期以降のデータをどう集めるか(どうやって属性とマッチさせていくか、利用者のデータ集めてく感じのような気はする)
  • そもそも選択肢と作品のマッチングをするのがしんどそう。精度が低いと需要ないだろうし

Springのセッターインジェクション

セッターによるインジェクション

@Component
public class SetterInjectionServiceImpl implements SetterInjectionService{

    //インジェクション対象
    private Test target;

    //セッターによるインジェクション
    @Autowired
    private void setTarget(Test target){
        this.target = target;
    }

    @Override
    public void show(){
        System.out.println("セッターインジェクションにてインジェクションされたインスタンス:" + target);
    }
}

呼び出し元のイメージ

       //このsetterにはすでにtargetが格納されている
        SetterInjectionService setter = context.getBean(SetterInjectionService.class);
        setter.show();

まとめ

  • DIコンテナに格納されたインスタンスは、@AutowiredのついたSetterによってフィールドに値が格納された状態のインスタンスとなる
  • というよりも、DIコンテナにインスタンスが格納されるタイミングで、@Autowiredのついたメソッドが呼び出される、くらいのイメージのがわかりやすいかも
  • その時、Autowiredのついたメソッドの引数は、インジェクションの対象となる
  • メソッドの引数に指定した値のインターフェースがインジェクションの対象にできない(Springの管理下に入っていない)と、起動時にエラーで落ちる