# Microservice
###### tags: `VS`
找到一個部落格
https://columns.chicken-house.net/2017/12/31/microservice9-servicediscovery/
## CH2 Implementing Microservice
### Introduction
不管任何大小的軟體,通常都會需要儲存資料。
我們常見的是三層的架構
Presentation Layer, Service Layer, Data Access Layer

#### Entity Framework
Entity Framework 是一個微軟建議的資料存取技術,屬於DAL層。
EF提供ORM的技術來處理資料庫,共有三種ORM的方式: Database First、Model First、Code First
```
EF6 技術在 2008 年首次隨附於 .NET Framework 3.5 SP1 和 Visual Studio 2008 SP1 中發行。
從 4.1 版本開始,則以 EntityFramework NuGet 套件的形式提供。
EF6 在 .NET Framework 4.x 上執行,這表示只能在 Windows 上執行。
EF6 仍然是受支援的產品,並會持續提供 Bug 修正和小幅度的改善。
Ref: https://docs.microsoft.com/zh-tw/ef/efcore-and-ef6/
```
```
Code First 這種建立資料庫、更新資料庫結構的過程,
整個步驟大致上就是「設計類別」→「產生更新資料庫結構的程式碼」→「直接更新」
(或「產生更新資料庫的指令碼」→「手動更新」),
真正難的地方是不要讓 Entity Framework 拿我們設計出來的 Model 去建出低效的資料表。
一般人對 Code First 的恐懼是它必須透過程式碼來控制 Table Schema、Field Attribute…等
來完成資料庫的設計,比起用 SSMS 透過 GUI 來操作顯得不是很方便。
```
#### Object-relational mappers (ORMs)
物件關聯式對應程式 (ORM)
ORM的優點
1. 以物件表現列, 以屬性表現欄, 用OOP概念操控資料庫
2. 隱藏SQL指令, 跨資料庫時不需修改應用程式的目的
3. 單一與發操控所有資料庫
4. 自動產生SQL指令, 降低人為的效率及安全性問題
#### Entity Framework Core
Entity Framework Core 基本上以 ORM 架構為主,延續 Entity Framework 的作法發展,
但 Entity Framework Core 不再支援 Database First 與 Model First 模式,
僅支援 Code First 模式,亦即使用程式碼來處理 **Model** 以及資料庫綱要對應的工作。
不再支援以 UI 為主的資料庫組態 (這是為了要適應 Linux 與 Mac 的開發環境),
且不論是何種模式 (Database First / Code First),都是以程式碼為主的環境對應,
不再有 EDMX (Entity Framework Metadata) 存在,
為達成這個目標,Entity Framework 提供了 Scaffold-Database 指令 (於 Package Management Console 中執行),允許開發人員由資料庫來產生 Model 的程式碼。
```
[Entity Framework Core]
Entity Framework Core (EF Core) 是完全重寫的 EF6,首次發行時間為 2016 年。
它隨附於 Nuget 套件,主要項目為 Microsoft.EntityFrameworkCore。
EF Core 是跨平台產品,可以在 .NET Core 或 .NET Framework 上執行。
EF Core 旨在提供類似於 EF6 的開發人員體驗。
大部分的頂層 API 都維持不變,因此使用過 EF6 的開發人員會對 EF Core 感到熟悉。
```
---
### Size of microservices
當開始建立MicroServices的時候, 有些基本概念要釐清
1. 在調整微服務的時候有哪些事情要被考慮到
2. 如何確認這個微服務和系統其他地方已經乾淨的切割開了
微服務著重在 "大小" & "粒度(Granularity)" 這兩件事上。
```
*Granularity* is the extent to which a system is broken down into small parts,
either the system itself or its description or observation.
粒度用來表示一個系統被打散成小單元的程度
```
從大方向的來看如何切割成微服務, 可以考慮下面幾個面向:
1. 變動的風險
2. 功能上的變動
3. 組織的變動 (切割的時候要確保組織內的人可以獨立運作)
4. 工具上的變動
---
### What makes a good service?
傳統的開發中,會有一個ESB作為中間層。
但在微服務的架構中已經沒有中間層了,因此考慮的重點在商業問題 & 如何用架構來處理這些商業問題。
下面列出幾個必要的特徵, 方便使用以及開發
1. 標準化的介面
2. 標準化的資料格式
3. 低耦合姓
#### ESB 解釋

```
ESB: enterprise service bus
ESB是由服務導向(SOA)架構發展而來, 這種類型的系統有以下主要功能:
1. 各式通訊協定支援
在設計上,ESB必須能夠與各式各樣的系統服務串連,而不同的服務可能採用各式不同的連接技術,
所以,ESB必需有能力跟不同的連接技術進行連接。
2. 資料格式檢核與轉換
ESB也可以進行資料轉換的工作,將資料轉換為應用系統可接受的型態,
一來可以做好資料把關者的角色,
二來也可以簡化資料承載的複雜度,類似一位稱職的翻譯官,伴演好各系統間溝通的角色。
3. 訊息繞徑的功能
在後續的段落,會跟各位討論何謂【服務】,
在這裡我先簡單的舉例,
假設我們將 “ 出貨 “定義為一個服務,而這個服務涉及到兩個行為,
一個行為為”扣除庫存”,另一為”開出發票”。
那麼當我們呼叫”出貨”這個服務時,前端的應用程式是不需要知道該服務的商務邏輯如何實作,
也不需要知道該怎麼呼叫後端的兩個行為,這一切都由ESB負責就可以了,
其優點是,將商業邏輯與實作完全的分開出來,將可以易於系統的維護以及企業流程的快速修改。
```
---
### Domain-Driven Design (DDD)
DDD: 領域驅動設計
要設計出好的模型需要3個腳色:
1. 瞭解現實問題的人 (領域專家)
2. 建造model的人 (軟體工程師)
3. 協助兩者合作的人 (DDD專家)
DDD 開發專注在理解使用者的需求,專注在 Domain 上,理解之後才開始寫程式碼,
在 DDD 開發上,是非常重視溝通,其需要一位懂專業領域的專家,幫助我們釐清問題,其 Domain Experts 可以是合作的客戶、可以是專案上的 PM 等等…
DDD 的特性:
1. 通常會傳住在"一個特定"的商業模型, 而非多個
2. 要可以重複使用
3. 低耦合性
4. 獨立於持久性實現而設計
5. 不可基於基礎框架
```
**DDD 的優點**
延展性
站在使用者的角度來看問題
有一套流程處理複雜的問題
幫助我們寫有組織且可測試的程式碼
所有的商業邏輯集中在一個地方
有很多 patterns 可以在專案中使用
**DDD 的缺點**
花時間
-溝通並理解商業邏輯,理解什麼問題該被解決
-將商業邏從應用程式中獨立出來
學習曲線
-不同的開發原則
-新的 patterns
-新的開發方式
只用在擁有複雜商業邏輯的專案上
-不適合用無複雜商業邏輯的專案,只有在做 CRUD 的情境上
-技術複雜但是商業邏輯簡單的情境,也不適用
```
DDD 對微服務的重要性在於可以拿來檢視是否切割得當,每一個系統應該都是唯一而且有自己的複雜程度
這段建議你,測試的時候可以單獨部屬其中一個service然後觀察他是否可以正常等待request
之類的XD
---
### The Concept of seam
這段就是提醒你想清楚為甚麼要用microservice再下手
再下一段內容中提到, 考量到module間的依存關係, 一般會建議從交接處著手改造~
#### Technology
接下來這段提到, 改造前你要先弄清楚每個feature到底用了哪些技術或framework
同時建議可試試著用一些和當前不同的東西~
#### Team structure
這一段提到說當你把架構都獨立後, 除了方便獨立作業外, 甚至可以考慮從外部群找適合的人選來幫(out sourcing)
#### Database
db要試著把結構打散, 從code的層面與功能層面兩邊下去做考量
要注意的是要曉得那些變動是可以被接受的? (不管是打散或是含其他表單做合併)
在DB的處理上首先要移除外來鍵關聯
```
外來鍵是一個(或數個)指向另外一個表格主鍵的欄位。
外來鍵的目的是確定資料的參考完整性 (Referential Integrity)。
換言之只有被准許的資料值才會被存入資料庫內。
舉例來說,假設我們有兩個表格:
一個 CUSTOMER 表格,裡面記錄了所有顧客的資料;
另一個 ORDERS 表格,裡面記錄了所有顧客訂購的資料。
在這裡的一個限制,就是所有的訂購資料中的顧客,都一定是要跟在 CUSTOMER 表格中存在。
在這裡,我們就會在 ORDERS 表格中設定一個外來鍵,
而這個外來鍵是指向 CUSTOMER 表格中的主鍵。
這樣一來,我們就可以確定所有在 ORDERS 表格中的顧客都存在 CUSTOMER 表格中。
換句話說,ORDERS 表格之中,不能有任何顧客是不存在於 CUSTOMER 表格中的資料。
```
#### Master Data
這裡的Master Data是指一些長年不變的資料, 建議使用config檔或hot code來處理他們
假如資料是所有的系統都需要的, 建議可以使用一個service來處理資料的傳遞
#### Transaction
當DB分開成多個小的DB後, 要回頭處理資料合併的問題, 並且要考慮到有可能出現部分服務失敗的情況
這裡的範例是, 今天有一個採購系統, 再客戶下訂單的時候另一個product service無法對印紀錄這筆訂單的資訊
(推測是可能產品數量無法更新之類的)
這邊給兩個可能的解決方案
1. 第一種解決方法是retry, 但是這樣就要記錄跟追蹤這些失敗的資料傳遞, 而且這個執行的存在時間可能會變得很長 (一個動作沒版法短時間被處理掉)
2. 另一種可能的方法是, 直接取消整筆訂單, 把整個資料傳遞全部取消掉, 也就是任一的失敗會讓整體全部返回原始狀態
---
### Communication Between Microservice
傳統單一的DB我們所有的service會用table來區分不同的service需求的資料, 現在則是以DB來區分
在單一DB架構下我們只會有一個repostory來存取DB,那在微服務的架構下我們會用API Gateway
```
這裡要解釋repostory:
前面我們有提到Entity Framework 是屬於Data Access Layer
用Entity Framework做DAL的問題如下:
(其實這個問題不只有使用Entity Framework會,任何的DAL實作都有這個問題。)
假設今天我們用的是Entity Framework作為DAL層,如果開發到一半,
突然不要使用Entity Framework,而是要改成傳統的ADO .Net作為DAL怎麼辦?
或者說如果要做單元測試(Unit Testing),肯定不希望在跑的時候還是連資料庫,
而是希望連一些假資料,這時候怎麼辦?
解決方法其實很簡單,就是把實際的DAL在抽一層出來,
就有了所謂的Repository Pattern。
Repository Pattern
一般來說,在寫Mvc裡面最長看到的Pattern就是Repository Pattern。
這個Pattern概念非常簡單,Repository其實有儲存庫的意思,
所以這個Pattern的意思是,把實際的DAL層透過所謂的Repository封裝之後,
從外面的角度來說是和Repository 溝通來取得資料,
至於Repository的資料來源是那裡,就不管了。
簡單來說, 真正存取DB的人, 叫repository
```
#### 微服務的基礎建設 --API Gateway
https://ithelp.ithome.com.tw/articles/10193116
API就是位於microservice跟UI的中間層,負責提供相對簡單的介面, 並讓prcoess在使用服務的時候更簡單
會需要這個gateway的存在是因為:
情境一:
想像我們現在有了 OrderService CustomerSerivce PayService ,
client端直接使用restful web api與三個service溝通,
每個服務都會相依於前一個服務的結果,
相較於傳統monolithic現在client需要完成一次交易除了要發三個request
還要加上中間等到response的時間….
(用戶: 你們新系統怎麼比以前還慢啊)
情境二:
又另外一個狀況發生, 因為過載或是服務故障,
OrderService1出了問題,好險我們有微服務,趕快啟動一個OrderService2來取代,
突然發現我們的client只認得OrderService1,
糟糕了………難不成我們需要每個服務掛掉啟動都通知用戶端………
(用戶:你們系統好不穩喔)
為了不客戶端直接跟子系統溝通, 或者說暴露太多的介面給客戶端,
一般會應用Façade pattern將子系統們封裝起來,
對client只暴露必要的介面, 降低client端與服務端的直接掛鉤,
在微服務的API應用上會給一個名詞 "API gateway"
#### Benefits of the API gateway
藉由API Gateway, 讓client不會依賴低層的服務本身,
抽換服務實體也不會影響client與API gateway間的通信,
也可以在API Gateway後封裝其他功能像是
load balancer, service discovery, service registry等
除了作為中間層讓user好使用外, API gateway另一個重要的用法是提供不同的client端不同封裝大小的API
client可以依照需求來呼叫不同的服務, 相對於原本的架構有彈性
像是在手機的client與在桌機的client使用的API服務的大小會有所差異
這邊的名詞: granularity, 翻譯為粒度, 就是在表達API封裝大小的差異
crouse-grained 為粗顆粒的
fine-grained 為細顆粒的
在這裡手機的client會使用粗顆粒的API, 桌機的則是細顆粒的
#### API gateway vs API management
這邊接著要討論API gateway是如何將client來的request導向實際的service
在API management solution中, 會提供一套完整的管理系統來管理API, 他們通常會包含以下功能:
1. 設計
2. 開發
3. 安全性
4. Publishing
5. 可擴展性
6. 監控
7. 分析
8. 可貨幣化?!
---
### Case study: Flix One Case
在這裡的架構是
service <> repository <> database
repository在這個世界中是一個micro component
在微服務的世界中有另外兩個詞:
model: 用來表示資料的物件(像是product & category會有各自的欄位內容這樣), 會透過EF Core來和實際的DB做溝通???
controller: 負責處理http api事務
---
## CH4 Testing MicroServices
### how to test?
micro services chanllenge:
1. they are independent and need to test indivitually but also need together.
2. many user scenario
3. team co-work to test if they were develop by different team
4. data dependency test.
### testing策略
建議QA在開發階段就拉進來
Proactive : 開發前就要想好測試, 開發目標要讓測試通過
Reactive : 寫好在測
### Testing Pyramid
unit test > service test > system end to end test
### type of tests
unit test
component test
integration test
contract
performance
end to end
#### unit test
functional / class test, testing inside API
#### component test
service <> service間的測試, bypass UI and test API
建議用mod 給一個假的物件然後focus在要測的東西上
#### integration test
service <> service間的測試, 測試那些有相依性的service的合作情況
#### contract
契約測試
consumer & provider間的介面測試, 驗證資料的提供是否正確
consumer driver test 以客戶為主的測試
#### performance
load test, stress test, 尖峰測試
#### end to end UI testing
包然UI DB Service全部
### Stubs and mocks
mocks
用於unit test的假物件, ex假的DB
stubs:
固定output的物件
## Ch5
understanding the deployment terminology
CD: continuous deployment (CD)
Continuous delivery:
迅速deploy讓使用者可以用
Build and deployed pipelines:
- Unit test
- Integration tests
CI server 可幫忙做test & create docker & push
成功部屬的條件
1. CI & CD : team member 要有共識能夠code要能夠快速的整合到code line上
2. 自動bulid & unit test - ex TFS, azure cloud
Isolation requirement
- source control isolation (因為services彼此分離)
VM vs Container:
虛擬話層級不同, 啟動速度不同
Docker:
Docker image: read only template
Docker registry: a lib of images
Docker file:
Docker container: instance of a iage
Docker compose: .yml allow you to define an application's component
Docker swarm: docker 提供用來管理群集的功能
VSTS: CI tool
## Ch6 Security MicroService
安全問題在開發的每個周期都應該被考慮
MicroService因為是分散式系統, 理論上更安全, 這個章節會探討以下內容
1. 為甚麼我們傳統的安全防護不可用?
2. OpenID & Azure Active Directory的介紹
3. OAuth 2.0
4. Azure API management ㄉ
5. internet secure
6. container secure
Authentication - identify of a user
Authorization - 授權每個使用者可以存取的內容

為何傳統的auth機制在micro service不能用??
之前作法是auth layer會將username pwd存在credential store, 並且建立cookie讓每個request都帶著可以用
```
Once the user credentials are verified for the session,
a session cookie gets created in the browser.
Unless the user has a valid session cookie, he cannot access the app.
Typically, a session cookie is sent with every request.
Within these kinds of monolithic applications,
modules can freely interact with each other since they are in the same process and have inmemory access.
This means trust is implicit within those application modules so
they do not need separate validation and verification of requests while talking to each other.
```
而在micro service的世界中, 因為每個service彼此獨立, 都需要去DB查找, 每個人的store都要sync,

接下來探討如何在inter service中處理auth的問題 (skip還是) 以及如何sync auth
新的Solution是Token Based
OpenID COnnect - authentication
OAth 2.0 - authrization
JSon Web Token (JWT)
他是一串數字, 包含header, payload, signature三個部分
包含很多user 資訊(ex Name)
User 在每次的request都必須戴上JWT, server可藉由JWT直接做authentication
可以不用像以前那樣要帶cookie上來
傳統 (cookie session based)
- server 需儲存session id並查找
JWT
- state 存在client不用查DB
- logon 後server回傳一串JWT token, 拿到後放在header - authorization
- 有特定format: 前置 Bearer
https://yami.io/jwt/
OAth2.0
可以讓3rd app可以獲得http上的一些resource, 看是user允許或他互動而得到許可
可用於mobile等等來的request
授權app可以做事情

第六步那邊有兩段, 這邊其實有四種作法
- Authorization code: This is the typical OAuth grant used by server-side web applications, the one you would use in your ASP.NET apps.
最嚴謹, 塗上的做法
Implicit: Authenticating with a server returns an access token to the browser, which can then be used to access resources. This is useful for single page applications where communication cannot be private.
- 不用grant直接拿到
Resource owner password credentials: This requires the user to directly enter their username and password in the application.
- 用account & pwd, 必須很相信client
Client credentials: This is typically used when the client is acting on its own behalf (the client is also the resource owner) or is requesting access to protected resources based on an authorization previously arranged with the authorization server.
- 不算是授權, 是直接要, 也要很相信client
OpenID Client:
架構於OAth2.0之上, 在某處紀錄帳密後, 都可以直接登入, 不用每個網站都要建立帳密
spec: 補足OAth2.0沒作authoncation的部分
沒有定義如何作authorization, 只說要JWT
OpenID.net
這本書要的是Azure AD,上面是業界標準
Azure Activate Directory
Azure API management
BFF(backend for frontends): 不同的client有不同的效同, 由gateway分配他們到不同的service做處理
API management屬於api gate way那段
好像Proxy,包含已下功能
1. Accepts API calls and routes them to your backends
1. Verifies API keys, JWTs, and certificates
1. Supports auth through Azure AD and OAuth 2.0 access token
1. Enforces usage quotas and rate limits
1. Transforms your API on the fly without code modifications
1. Caches backend responses where set up
1. Logs call metadata for analytics purposes
(页码180).
Publisher portal: This is the administrative interface to organize and publish an API program.

(页码180).
Publisher portal: This is the administrative interface to organize and publish an API program.

(页码180).

Container Sercurity

Summarize:
1. 原本tokenbase為了要讓microservice可用, 所以提到openID, OAth2.0用來說明azure id符合
2. 講到每一層的功能
3. container security
## Ch7 Monitoring Microsices
#### why monitor?
control your cost!!
- health monitoring:
check services online or not. Show you the request failures and success rate.
- Avalibality monitoring:
check services work correct or not. How long it break and how long to take to back.
- Performance monitoring:
web-based performance. check request take time or request per hour, customer per request, customer request
transaction time.
- Security monitoring:
check Dos or Injection attacks. provide Auditer.
- SLA monitoring:
based on the monitoring above. You may check how is your service work right now and give it a score.
you should provide RCA.
Service provider will provide SLA to deal with customer, if service fail, you may need to
pay to you customer. Based on SLA.
- End user monitoring:
monitor user's using time or payload.
#### Troubleshooting system failure:
its hard to find root cause.
Monitoring Challenges:
- scale : complex dependency on services.
- devOps mindset : devOps is someone who dev and support & take care of customer. they are buzy and not sure how they do.
- data flow visualization : too many log to know.
- testing of monitoring tools : you should test your tool.
Monitorting Strategies:
- application/framework based : framework is good and provide many tools.
- real user monitoring : check time for transaction
- semantic monitoring & synthetic transactions : create a fake page and check the request time that services take. (maybe a specific word on page.)
- profiling : services reponse time, thread, memory usage.
- endpoint monitoring - services may on many machines. Check one of them and it represent the whole services status.
Logging challenges:
- log is not presist : sometimes log were in container and you can't always get it. Logs may remay only in runtime and not inside image.
- the number of services that consitute a transaction. : you may have a lot services and they have dependency to each group of services. Its hard to know who dead.
Logging Strategies:
- centralized logs : structure your log and store in same place.
- correlation ID in logging. Give it a id to your transaction.
- Semantic logging. : something like windows event viewer.
Monitoring in Azure Cloud:
- Azure Diagnostics : collect and analyze
- application insights : framwork based, collect and you may write something.
- log analytics : analyzer
Storing diagnostic data using Azure Storage:
store your log on Azure Storage via APK or commandline.
Specifying a storage account
ServiceConfiguration.cscfg can tell where to store your blob.
Azure Storage schema for diagnostic data:
- wadlogtable : write log on runtime
- waddiagnosticInfrastructureLogsTable
- WADDirectoriesTable:IIS
- WADPerformanceCounterTalbe:performance
- WADWindowsEventTable: event
APM : application perfomance management
tuning performance framework based tool.
ELK stack:
elasticsearch : full text search engine. for finding logs
logstash : log analyzer
Kibana : log visualize
Splunk:
can do : mail, trigger point, run script.
alerting
reporting
## Ch8 Scaling Microservices
為了處理使用者暴增
Scaling vs Performance
Scaling專注在service size, 如VM數量
##### How to ?
- 垂直 scaling up
Upgrade your computer. 設備變好但數量不變
會變貴且效果不好,成本與效能非線性
- 水平
增加電腦數量, load balance重要
線性成長的成本
分散式的工作不能綁定特定環境或狀態, 避免資料間的關聯,
Scale Cude:
[](https://goo.gl/images/aQ1wmC)
X: scale by cloning
Z: load balance 本人
Y: role & action來分, microservice在做的部分
特徵:
1. cost & services 的關係曲線
2. 使用者的數據 找bottle neck
3. 高效率使用基本resource
4. 自動化擴增
5. 了解每個部份的硬體需求 好方便計算成本
6. dependency也要注意, 要可一起放大
7. 容錯
8. data的部分也要可以放大
##### Scaling the infrastructure:
- Autoscale - instance handler
- Resource manager - load balancer
- protal - scale set (?????)
以上微軟的工具
##### Azure Monitor autoscale:
工具, 會根據你設定的東西來放大
##### Docker Swarm:
Kubernetes (AKS) - K8S (現行)
推薦你區分 read & write權限到不同機器
##### Caching:
會有很多地方需要cache來避免效能消耗
- 可以用http的機制
- 也可以價另外一台電腦專做cache, 或多個,來降低資料擁有者的負擔
##### Redundancy & fault tolerance:
容錯
circuit breakers: 保險絲系統 (發生狀況要知道避開, balancer要知道處理)
service discovery: 每個service的位子要有名單記下來, 這個service要很可靠, 要可以知道上下線 & 動態區分工作,
健康度, 絕對不能中斷自己的服務
工具: zookeeper, consul etc
---
## Ch9. Reactive MicroService
### Message Driven: a core of reactive microservices
reponsiveness : 快速回應
resilience : A-sync calls, 由事件來驅動,
service間不會直接溝通, 都走event, 有點像OSCE都走queue, 彼此之間不相依
### Event Communication:
event store: event要執行的動作, 走restful api,變成data driven而非code driven, 流程由帶來的資料來決定
### Security
token based, JWT, OAuth bearer token.
不要自己刻一套
### Scalability
處理事件的人是中性的, 只知道要拿東西出來, bind對應的人, 然後呼叫
### managing data
如何確保資料傳輸是完整的, 如果有狀況如何處理, 介紹了一個pattern [CQRS](https://docs.microsoft.com/zh-tw/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/cqrs-microservice-reads)
Event Sourcing pattern: 如何做到回應型的MicroService作法