2016年11月18日,参加了春节庆典2016的记录
最近的Spring产品和案例讨论都很有趣,让我再次深刻地意识到有了Spring Cloud,可以用Spring Boot来构建微服务。
据看起来,每个人都在努力解决Spring容器启动缓慢的问题(比如缩小转换为Bean的类范围),而且似乎在Spring 5中会引入一种叫做@Indexed的功能,但是我听不懂英语,不知道具体是什么意思…
在许多场景中,我对Swagger的印象是它无处不在。
然后,Work先生的演讲令人印象深刻(将2,000名开发人员的产品从单体架构转变为微服务架构)。
尽管在功能上或者在领域上进行分割,但实际上不知道应该如何进行分割。在基础设施驱动的分割中,根据具体问题的需求,自然而然地采用了微服务架构的方法。在这个过程中,我留下了一个印象,即对领域的本质讨论逐渐成为可能。
途中有传言说在分割数据(包括搜索索引)方面存在困难,但现在这方面的进展如何呢?
Spring Framework 5.0 主题
– Spring 5
+ 5.0版本:要求JDK 8+、Servlet 3.1+、JUnit 5
+ Spring 5.1版本将支持Servlet 4.0
性能改进
-
- Alternative to component scanning
Pre-computed index at compilation time: @Indexed
具体的な仕組みは聴きとれず・・・
ASM meta-data cache
これも分からなかった・・・
Rewrite of AntPathMatcher
Zero-copy transfer of org.springframwork.core.io.Resource
JDK 9: Java Development Kit 9.
-
- Jigsaw: naming convention based on maven metadata
symbolic name
spring-context-4.2.4 RELEASE.jar => spring.context
module.my.app {
requires spring.jdbc;
}
HTTP/2 可以进行中文本地化。
-
- HTTPは20年経っている
-
- Servlet 4.0 – September 2017 -> spring 5.1
- tomcat / jetty / Undertowでは既に使える
响应式编程
-
- more for scalability and stability than for speed
CPUを最大限活用
功能式的网络路由
应用重构技术
从Struts迁移到Spring MVC
-
- spring mvcとspring bootでshare 70%超
-
- 初期開発時に採用されたフレームワークは長期で使われがち
初回更改時は、システム基盤更改(OS/HW/MWのEOL対応)と簡単な機能追加にとどまるケースが多い
2回目の公開時は、システム全体の刷新を前提にした可初代さんが確保されやすい
移行
strutsはフルスタックなフレームワークではないため、ビジネスロジック以降の構成は様々、汎用的なツール化は困難
効率化のための各種ツール、プロセスや実施要項、見積もり方法など多岐にわたる
そっと移行して延命する?、アクティブに改修していくならいっそ作り直す?
移行を機械的に移行すれば、テストを省略できる
移行元がSSH構成だと・・・
Action -> Controllerが一番つらい(Actionをどう使っているかがプロジェクトによって様々)
ドメイン層は、元々レイヤリングされていれば対処しやすい(refactoringせずに流用する工夫が重要)
インフラ層は、ORMの親和性が高いものを選べば比較的対応しやすい
例子 (li4 zi5)
- strutsにもspring mvcにもあるが微妙に異なる仕様/挙動のものを、事前に検出して手当てすることが重要
架构方面
-
- session/request格納データの取得方法の違い
struts1ではrequest/sessionスコープに同じキー名で異なるデータを利用していた
@ModelAttribtes, @sessionAttributesを採用(スコープの違いはアプリケーション側からは透過的)
1 requestで複数のビジネスロジックを呼び出した際に、前段のビジネスロジックの処理結果が引き継げない
複数Actionをforwardでchainしていた場合に発生
Spring MVCでは、modelからrequest copeへのデータ反映はviewの解決時のみ(forward毎にmodelが初期化される)
forwardをやめて、methodに切替
功能面 -> 功能麵
-
- transaction tokenがないことにより、画面遷移の挙動が変わってしまった
TELASOLUNAで代替機能を開発
validation
正規表現で空文字がチェック対象になる
日本語用の独自チェックルール
Cloud Foundry与Wagby
-
- Cloud Foundry:再起動するとローカルデータが消えるので、本格的な運用には有料サービス必須だが、大企業にはメリットある
データベース
ログ保管
バイナリファイル保存
全文検索エンジンのindex
10年前からwagby販売開始、直販せず全国20社のパートナーと協業体制
Cloud Foundry
ssh, scp, sftpもできる
アプリケーションを停止、再起動するとdiscの内容はすべて消える(必要なファイルはバックアップ)
marketplace、manifest.ymlでbindする、push時に設定が自動的に反映される(CloudConfig, Cloud Profile)
ファイルはネットワークストレージに書くとして、Azure/S3などでプログラムを切り替えないといけない
SalesforceやKintoneのようなインフラがないwagbyにとっては、Cloud Foundryに乗せれば同等の信頼性を担保できるためありがたい
使用Spring Security构建Web API访问控制的最佳解决方案。
“基本验证?API密钥?OAuth 2.0?OpenID Connect?” – 参考:http://www.slideshare.net/daisuke_m/spring-day-2016-web-api
-
- 認証と認可
認証:通信相手が誰か、確認すること(=なりすましでないこと)
認可:リクエストが許可されるかどうかを決めること
多くの場合、認証した上で、「その主体が権限を持つかどうか」の観点で認可する
private networkであれば、認証そもそもいる?、SSLそもそもいる?
global networkの場合は、SSL/TLS必須(天気予報ですらOpenWeatherMapは最近は認証している)
認証:what you are(顔、声、指紋), what you have(身分証、携帯電話), what you know(パスワード、秘密の質問)
credentialの分類
静的・無期限:パスワード
静的・有期限:OAuthのアクセストークン・セッションID
動的:リクエスト署名(HMAC)
基于密码的认证(BASIC)和摘要认证(Digest)
-
- ブラウザ:HTTPではパスワードが平文で流れるので論外、ログアウトできない
-
- APIにおけるBASIC認証 over HTTPS:決定的な否定理由が見つからない
OAuth2.0でも技術要素として使っている
ただし、静的・無期限なcredentialが毎回流れるのでAttack Windowが大きい、SSL/TLSとて万能ではない
Digest認証
nonceを利用したchallenge&responseでHTTPリクエストが必ず2往復する⇒Web APIには向かない
API签名
-
- AWSのAPIが採用
-
- HMAC(ハッシュ関数に基づくメッセージ認証符号)
秘密鍵を共有し、元のメッセージを秘密鍵でhash化したものを一緒に送って署名する
OAuth1.0aはこの仕組みを利用、リクエストごとに計算が必要
クライアントを神に位置づけるのであれば、適切な選択肢だが標準化が望まれる
OAuth(开放授权)
-
- 認証をするための仕組みではない、認可をするための仕組みでもない
-
- Aがあらかじめもっている認可をBに対して部分的に委譲するための仕組み
-
- アクセストークン:静的だが有期限
-
- 考え方
一般的なアクセス制御はAPI clientが全権を持っていて、エンドユーザは認証/認可をして一部を利用
OAuthはAPI clientが、エンドユーザから移譲を受けた権限を代理で実行
Spring Security
Authentication:認証
grantedAuthority: エンドユーザが持つ権限(認可)
oauth2authentication:クライアントの認証
scope:OAuth2においてエンドユーザから移譲を受けた権限の範囲
Client Credentials認証においてクライアントが持つ権限(認可):例)twitterのpublic timeline
开放ID Connect
-
- OAuth2.0よりシンプル、Web APIの認証にはあまり関係ない
-
- 自身でユーザのパスワードを管理したくないアプリが認証するための仕組み
- OpenID ProviderはID/passを確認したら、「この人は〇〇さんだよ」というデータに電子署名をつけて持ち帰らせる
让我们将您的春云应用可视化!
使用Elasticsearch和Sleuth来实现可视化的实际应用
微服务开发的痛苦
-
- Devの苦悩
サービスの数が膨れてしまい、サービス同士の依存関係が分からなくなる(open call hierarchyで見られない)
改修の影響範囲、エラーの原因、そもそも使われていないサービス
Opsの苦悩
監視すべきサーバやプロセスの数が多い
ログファイルが分散してしまう、どのログファイルを見ればいいか
Opsを考慮したDevの苦悩
問題の兆候をログから検知しづらい
無視していいログか
ロギング仕様を事前に全て決めきって守らせる?Agilityが落ちる・・・
見るものが多い⇒可視化(グラフにしてトレンドを掴むところから始める)
工具集
-
- サービス間の依存性:Spring Cloud Sleuth + Zipkin
ボトルネックを探す、サービス間の依存性を把握
ログファイル:Elasticsearch + Logstash + Kibana + Filebeat
リソース状況:Elasticsearch + Kibana + Metricbeat
1人月くあいあれば組めるよ!
服务依赖性的可视化
-
- 主に開発者向けの可視化
-
- Distributed Tracing:リクエストに共通のIDを振って、HTTP/AMQP headerなどで伝播させて処理を追跡
-
- Spring Cloud Sleuth: filter的に動くイメージ(HTTP request/response時にZipkin Serverに呼び出し情報を送る)
dependenciesを追加コードの変更は一切なし
Zipkin
mainメソッドを持つクラス1つで立ち上がる
日志的可视化
-
- (問題が起きたときだけでなく)日常的にログを見て想定外の事象が発生していないかを確認することでサービスレベルが格段に上がる
ごく少数の人がエラーになっているが、問い合わせが来ずに気がつかないこともある
アプリケーションログの可視化
システムが安定稼働しているのかを把握
validationエラーが特定のフォームに偏っていたらおかしい、とか
アクセスログの可視化
適切なレスポンスを返せているのかの把握(400/500を返していないか、レスポンスタイムが大きくなっていないか)
急激なアクセス増などが起きていないかの把握(攻撃を受けた)
Elasticスタック(ELKスタック+Beatsシリーズ)
Logstash: Filebeatからデータを受け取り、加工して(parseしてjsonに変換)、Elasticsearchに転送する
kibana: 想定しているものを非表示にしてfilterしていく⇒毎日0件であることを確認すれば想定外の事象が発生していることに気がつける
Cloud Watch Logsより複雑なfilterをかけられる
OSSでは他の選択肢がほぼない、商用製品ではSplunkがある
雑にログを入れておいて「あとから」集計軸を変えられる(時系列の数値データを記録するツールでは難しい):Elasticsearchの検索の高速さ
系统资源的可视化
-
- Zabbix, Mackerel, DataDog, Cloud Watchなどツールは多数ある
-
- アクセス数とCPU利用率の相関を見たい⇒Elasticsearchで並べてみる
-
- MetrixbeatはjsonをElasticsearchに送る(Logstashの加工は不要)
- 売上とかも並べてみるとおもしろい
可视化和Kafka
-
- 可視化システムの安定化、情報の欠落を防ぐ
-
- キューのようなもの、ただし過去1週間分のデータを保持しており、いつでも取り出し可能(AWS Kinesisに近い)
-
- マイクロサービスとZipkinとの間、Logstashとの間にKafkaを挟む
-
- Elasticsearch/Logstashを停止する、Logstashの設定誤りを修正するとき
-
- Spring Cloud Stream
サービス/ミドルウェアを止めても、メッセージを欠落させることなく処理できるか?
実は、BeatsとLogstashの間はバックプレッシャー型の独自プロトコル
在超大规模项目中尝试微服务架构
公司名稱:株式會社Work Applications
網址:https://speakerdeck.com/kingofreverb/microservices-architecturewochao-da-gui-mo-puroziekutodeyatutemita
HUE的意思
-
- HUE:COMPANYの機能を基本的に全部入れる
Cloud Native
分散処理機構:膨大な量の帳票の集計の高速化(一億明細とか)
人工知能:学習に基づく、Input Less化
応答速度にコミット:100msで応答するという挑戦
超大規模
開発者3000+(日本、上海、シンガポール、インド)
CI 30名、運用チーム 15名
MSAへの移行は難しい、でも出来る!
技術的な難しさは、言うても組み合わせ、実はそんなに新奇性はない
精神的な難しさ:「諦める事」への慣れ、「仕様」という言葉の魔法感、パラダイムシフトを許容できない(目に見える範囲で「改善」を積み上げてしまう)
HUE的变迁
-
- RDBMSからの脱却:Cassandra、Spark
-
- バージョンアップ:3週間かかる⇒monolithicってこと・・・
年に百万ステップとか増える
ビルドに14時間(テストも5hrかかって流せない)、浪費壁(warを動かすには32GBのメモリが必要)
サービスとしても、本来は業務単位で切り売りしたかった
依赖的战国时代
-
- まずは依存性の調査(mvn dependency:tree, Dependency Analyzer)⇒分からない・・・
-
- レポジトリ分割闘争
分割する:管理する単位自体を変えるということ
1レポジトリ?細かく分けていくか?(treeは1つにしたかった)
1レポジトリ
インテグレーションレベルでの問題発見の早さ
cloneに時間がかかる、Googleはbuildツールも自作している
レポジトリ分割
clone, build, testが早い
HUE
Pre-marge build
Smoke Test(Dockerベースで起動確認だけする、health check)
インテグレーションレベルの問題:0から環境を毎日作ってテスト、Immutable Infrastructure
分割(「意味ある単位」が分からない)
業務機能での何となくの塊(完璧でなくていい)
共通機能と業務機能は絶対に別
切ってみてから分かることもある
イテレーション単位で狙いを定めて切り離す
共通部分は意外と切り出せた(refactoringは独立宣言後でも大丈夫)
中东和北非地区的黎明期
-
- 結局は依存の問題
-
- 分けられない理由:分けると何が起こるか分からない(どうなっているか分からない不安)
-
- FWに入っていてもサービスに切り出せるもの(承認ワークフロー、spreadsheet)
-
- 普通の景色に戻す:ApplicationとLibrary
Libraryは使われるだけ、中にしか依存がない(ユーティリティなど)
Applicationはサービスそのもの、Application間はWebAPIでやり取り
ドメインが分割不可なら、開発組織単位で分ける(Stakeholderが減る)
データの分割はとてつもなく難しい(承認ワークフローってみんな使うけど誰のもの?)
検索Indexどうするかとか
そろそろ本質に気づいてくる⇒ドメインとは
売りたい単位、バージョンアップしたい単位、ライセンスの単位
现在是MSA。
-
- インスタンスコストは高い
-
- Kubernetesを導入
-
- M/Wリソースは共有できないといけない⇒Multi-tenancy
-
- AWS LambdaなどのManaged Service活用(時間課金⇒100ms課金)
-
- 出納大臣(課金API)、性能大臣(負荷試験と緻密なCP)
-
- war ⇒ Docker
Dockerfileを成果物にする(Buildまで開発チームで責任もってもらう)
運用も移譲
build:開発者が決める
deploy:Ansibleベースで環境構築スクリプトも書いてもらう
Scaling Factorとか非機能要件
モニタリング:Prometeus
CIチームの役割
Jenkinsで魔法をかけない(Monolithicアプリは往々にして魔法でできている)
インテグレーションレベルでの問題解決
開発クオリティを担保する方向へ
总结
-
- インフラドリブンでいく
Jenkins的なビルドツール
Gitレポジトリ申請フロー
依存性をチェックする仕組み
レビュー機関
製品としてのコンセプトを判断
Architeccture
M/Wリソース消費
800万⇒20-30万くらい(JSも含めて)に分割
阿米布洛进行了大规模的系统更新,并通过Spring框架提供支持。
-
- 5300万人、サーバ数百台、60万リクエスト/m
ページが見られない = 広告が表示されないため売上に直結
DB構造や、フロントエンドのHTML/JSは書き換えずに、バックエンドを刷新
Springを選んだ理由:@Controller, @Service, @Repository⇒レイヤーの共通認識になる
保守性减弱
-
- レイヤー
Controller:requestを受けて結果を返す
Facade:ユーザの一操作に必要なserviceの呼び出し(ブログ投稿⇒記事投稿、twitter連携)
Service:最低限まとめておくべきビジネスロジック(記事のデータ保存と、記事数のインクリメント)
Repository
Springfox + Swagger
annotationから生成
endpointのきれいな一覧だけでもありがたい
开发成本
-
- ローカル開発環境を構築
spring bootでfat jarを作成、gradle bootRunで起動
プロダクトごとにリポジトリが分散:ソースコードもリリースジョブも再利用性が低い
リポジトリを1つにして、マルチプロジェクト化
共通化したことで起動の際に不要なクラスが大量にBean生成される(設定も必要)
FacadeクラスがAutowiredしているServiceクラスだけをBean化するInitializerを作った
宣言した接続先に関連するrepositoryだけをBean化するInitializerを作った
视图与业务逻辑之间存在强烈的依赖关系。
-
- API Centric
AMP対応やスマホ版フロントエンド刷新(React/Redux)も特に対応なく完了
通信コストの増大
複数レイヤにキャッシュを入れて対応
Repositoryでキャッシュ(データ更新時に消す)
clientでキャッシュ
API呼び出し元/先が分かりづらい(method callでなくなったので)
使用Spring Cloud Stream、Task和Data Flow的数据微服务
-
- Spring XD(eXtreme Data)
XD Admin、ZooKeeperを介して協調、DI Container間にMessage Brokerが挟まる
stream1 = http | cassandra
アーキテクチャが古い、Modern PlatformsではCordinationをしてくれる
Cloud Native Redesign
standalone executable applications(spring boot)
既存のmodern platformで動かす
Data Microservices
unixのpipe
pipeがMessage Brokers
spring bootのapplicationをmessage brokerで繋ぐ
Architeccture
orchestrate: Spring Cloud Data Flow
Long Lived Stream Applications: Spring Cloud Stream
Short Lived Task Applications: Spring Cloud Task
Spring Cloud Deployer(SPI)
Spring Integrationのコンポーネントを利用している
春云流
-
- source | processor | sink
-
- @EnableBinding
-
- Rabbit MQ, Apache KafkaがProduction-Ready
-
- Reactive API Support
Fluxを使うとWindow処理ができるようになる(集計とか)
backpressureがまだ効かない
Spring Cloud Stream App Service
Spring Orchestration in SCDF
maven/docker
Consumer Group -> Spring Cloud Data Flowでデプロイすると自動でグルーピングされる
groupの中のどれかにデータが流れる
Partitioning Support(Stateful Stream)
Spring Flo: GUI
Programmable Reactive Processor
春季云任务
-
- CommandLineRunner or Spring Batch
結果はTask Repositoryに格納される
cloudにdeployして一瞬実行して終了できる、結果は永続化する
Spring Cloud Data Flowを使うと、クラウドプラットフォーム上の短命処理として利用できる
安装 PCF Dev
- Cloud Foundry on your laptop