第十三課:微服務基本知識-微服務調用及運行過程


3. 微服務調用及運行過程

3.1 為什么分析微服務過程調用

在實際的項目中,微服務之間涉及到業務代碼的部分,調用邏輯非常復雜,對於工程師而言,熟悉組件之間的調用關系,方便以后業務模塊開發,集群部署與自動化編排過程中有非常大的幫助(基礎),並且能夠非常清楚哪些應用應該對外,哪些可以不用對外以及服務是怎樣存活。

  • 在微服務中涉及的組件:注冊中心,配置中心,服務提供者,服務消費者,路由網關

3.1.1 本案例涉及的服務有以下幾種

注冊中心服務(nacos),配置中心服務(nacos),服務提供者(passport),服務消費者(restTemplate,Feign),路由網關服務(Spring Cloud Gateway)

3.2 組件服務調用基本流程

  • 客戶端瀏覽器輸入url
  • 訪問網關負載均衡(7層,可以是nginx/haproxy)通過負載均衡分發請求到spring cloud gateway網關
  • 網關在即受到來自負載均衡的請求之后,根據url地址匹配到服務名稱,調用后台的restTemplate服務
  • restTemplate在接收到來自網關的請求以后,通過注冊中心查詢到服務列表,將請求服務列表中的服務,最后返回結果。

avator

3.3 組件內部接口調用流程

負載均衡->網關->消費者->服務提供者

3.4 微服務實戰(單機部署)

3.4.1 運行微服務

安裝java環境
將java安裝包(jdk1.8.0_192.tar.gz)傳到主機/usr/local/下並解壓縮
編輯環境變量/etc/profile

vim /etc/prolfie
export JAVA_HOME=/usr/local/jdk1.8.0_192
export JRE_HOME=/${JAVA_HOME}/jre
export PATH=${JAVA_HOME}/bin:$PATH
#應用
source /etc/profile

3.4.2 安裝nacos(單機)

下載注冊中心nacos

https://nacos.io/zh-cn/docs/what-is-nacos.html

wget https://github.com/alibaba/nacos/releases/download/1.1.4/nacos-server-1.1.4.tar.gz
tar zxvf nacos-server-1.1.4.tar.gz 
cd nacos/bin
sh startup.sh -m standalone

登陸訪問頁面
http://192.168.68.152:8848/nacos
username:nacos
password:nacos

導入配置文件
nacos_config_provider.zip ----> provider-passport-config.yaml
nacos_config_gateway.zip ----> spring-cloud-gateway.yaml
可以從頁面修改配置文件中注冊中心的IP地址
spring-cloud-gateway.yaml

        server-addr: 192.168.68.152:8848
        file-extension: yaml
      config:
        server-addr: 192.168.68.152:8848

provider-passport-config.yaml

server-addr: 192.168.68.152:8848

生產使用集群模式(至少3個節點)

  1. 安裝mysql5.7.25(主從)
  2. 導入數據庫(nacos-mysql.sql)
  3. 修改配置文件(application.properties cluster.conf)
  4. 啟動(sh startup.sh)

3.4.3 安裝redis

yum install epel-release -y
yum install redis -y
#修改密碼
vim /etc/redis.conf
requirepass 123456
bind 0.0.0.0
#開機啟動
systemctl enable redis
systemctl restart redis
systemctl status redis

查看端口監聽

[root@localhost ~]# netstat -lantup | grep 6379
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      12850/redis-server  

修改配置文件spring-cloud-gateway.yaml

redis:
    host: 192.168.68.152
    port: 6379
    password: 123456

3.4.4 后台服務provider-passport

上傳測試包

mkdir springcloud && cd springcloud
[root@localhost springcloud]# ll
total 449792
-rw-r--r-- 1 root root  91330721 Aug 26 10:18 consumer-feign-passport-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  90430214 Aug 26 10:28 consumer-passport-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 105609972 Aug 26 12:27 gateway-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  49134278 Aug 26 10:27 monitor-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  33651884 Aug 26 10:24 passport-demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root  90419589 Aug 26 12:14 provider-passport-0.0.1-SNAPSHOT.jar

3.4.4.1 運行provide passport

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar provider-passport-0.0.1-SNAPSHOT.jar

3.4.4.2 服務注冊

從頁面查看我們剛才啟動的passport服務已經注冊到注冊中心
avator

3.4.4.3 訪問后台服務接口

http://192.168.68.152:8086/v1/auth/login
返回json內容如下:

{
msg: "demo passport api",
api: "/v1/auth/login",
type: "passportProvider",
status: 200
}

http://192.168.68.152:8086/passport
返回json內容如下:

{
msg: "后台服務passport",
api: "/passport",
type: "autoNacosConfig",
status: 200
}

2.4.4.4 驗證配置中心修改配置功能

通過nacos頁面修改配置文件provider-passport-config.yaml的內容后,再次調用后台服務接口,可以看出我們通過配置中心修改配置以后並不需要重啟服務,配置即時生效。

#修改msg字段
data:
  msg: '后台服務passport-修改配置測試'

再次調用接口http://192.168.68.152:8086/passport

{
msg: "后台服務passport-修改配置測試",
api: "/passport",
type: "autoNacosConfig",
status: 200
}

注意:並不是所有的配置可以在不重啟服務的情況下生效,比如數據庫。

查看passport服務日志可以看到配置變更以后重新生效的過程
avator

如果能夠使用nacos注冊到注冊中心則使用臨時實例,否則使用永久實例

https://nacos.io/zh-cn/docs/open-api.html

類型 服務端 客戶端
主動發送 配置文件發送,統一更新 發送心跳
被動接受 心跳信息 配置文件

客戶端:

2020-08-27 09:50:24.077  INFO 20140 --- [ing.beat.sender] com.alibaba.nacos.client.naming          : [BEAT] [] [] send beat to server: {"cluster":"DEFAULT","dom":"provider-passport","ip":"192.168.68.152","metadata":{"preserved.register.source":"SPRING_CLOUD","content":"/"},"port":8086,"weight":1.0}

企業部署nacos注冊中心部署的建議:

  1. 幾個環境幾個注冊中心(開發環境1台機器1個注冊中心,生產環境3台機器(集群)1個注冊中心,測試環境1台機器1個注冊中心),幾個環境幾個配置文件(比如passport-config-dev.yaml,passport-config-test.yaml,passport-config-prod.yaml)
  2. 1個配置中心,不同的ns(不建議)
  3. tomcat瓶頸優化的方法:1.橫向擴展,增加容器的數量。2.代碼優化修改並發連接數。

3.4.5 運行消費者consumer-feign-passport服務

3.4.5.1 運行消費者feign服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar consumer-feign-passport-0.0.1-SNAPSHOT.jar

3.4.5.2 服務注冊

再次通過nacos頁面查看服務注冊情況
avator

3.4.5.3 訪問消費者Feign服務接口

http://192.168.68.152:9092/v1/auth/login

{
msg: "demo passport api",
api: "/v1/auth/Feign controller",
type: "feign",
status: 200
}

http://192.168.68.152:9092/passport

{
msg: "后台服務passport-修改配置測試",
api: "/passport",
type: "feignPassport",
status: 200
}

3.4.6 運行消費者consumer-passport服務

3.4.6.1 運行消費者consumer-passport服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar consumer-passport-0.0.1-SNAPSHOT.jar

3.4.6.2 服務注冊

通過nacos頁面或者從服務日志可以看到注冊成功

2020-08-27 10:41:27.177  INFO 21027 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, consumer-passport 192.168.68.152:9091 register finished

3.4.6.3 接口測試

http://192.168.68.152:9091/v1/auth/login

{
msg: "demo passport restTemplate /v1/auth/login api",
api: "{"msg":"demo passport api","api":"/v1/auth/consumer-passport","type":"passportProvider","status":200}",
type: "restTemplatePassport",
status: 200
}

http://192.168.68.152:9091/passport

{
msg: "demo passport restTemplate /passport api",
api: "{"msg":"后台服務passport-修改配置測試","api":"/passport","type":"autoNacosConfig","status":200}",
type: "restTemplatePassport",
status: 200
}

3.4.7 兩種消費者調用的區別是什么

restTemplate和Feign的區別
在spring cloud 中有兩種服務調用方式,一種是ribbon+restTemplate ,另一種是feign。相對來說,feign因為注解使用起來更簡便。而restTemplate需要我們自定義一個RestTemplate,手動注入,並設置成LoadBalance。
內部調用:(內網相通)使用feign調用,調用方式為http://服務名/接口地址,比如:http://provider-passport/passport
跨地址/區域調用:(走外網調用)使用restTemplate調用,調用方式為http://服務IP地址/服務名稱/接口地址,比如:http://192.168.68.152:8086/passport

我們在Java項目中調用接口有四種方式,分別是:
Httpclient
Okhttp
Httpurlconnection
RestTemplate

從消費者服務接口返回的內容與從passport提供者接口的內容一致,原理是訪問消費者接口反向代理到提供者接口,獲取返回內容。為什么要這么做的原因是如果后台有多個提供者的時候,消費客feign提供了負載均衡的作用。

3.4.8 運行網關服務

3.4.8.1 運行網關gateway服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-jar gateway-0.0.1-SNAPSHOT.jar

3.4.8.2 注冊服務

同樣的在nacos頁面或者服務啟動日志中可以看到服務注冊成功信息

2020-08-27 11:19:37.475  INFO 22094 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, spring-cloud-gateway 192.168.68.152:9000 register finished

3.4.8.3 接口測試

通過gateway訪問后台服務
通過consumer-feign-passport訪問后台服務/v1/auth/login

正常請求feign調用
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=1231

{
msg: "demo passport api",
api: "/v1/auth/Feign controller",
type: "feign",
status: 200
}

http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123

{
msg: "后台服務passport-修改配置測試",
api: "/passport",
type: "feignPassport",
status: 200
}

正常請求restTemplate調用
http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222

{
msg: "demo passport restTemplate /v1/auth/login api",
api: "{"msg":"demo passport api","api":"/v1/auth/consumer-passport","type":"passportProvider","status":200}",
type: "restTemplatePassport",
status: 200
}

http://192.168.68.152:9000/consumer-passport/passport?token=123123

{
msg: "demo passport restTemplate /passport api",
api: "{"msg":"后台服務passport-修改配置測試","api":"/passport","type":"autoNacosConfig","status":200}",
type: "restTemplatePassport",
status: 200
}

3.4.9 鑒權功能

我們在訪問網關接口的時候,需要帶token才能正常訪問,否則會報非法請求
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login

{
code: 401,
cause: "Token字符串為空!",
message: "非法請求"
}

3.5 注冊中心服務列表

服務必須存在與服務列表才能被調用
avator

3.6 微服務治理

3.6.1 服務熔斷處理

在正常服務訪問的情況下,后台服務不可用的情況下,或出現500的錯誤,返回客戶端很不友好,並且接口之間的調試比較困難,因為不知道后台服務發生了什么錯誤。
將后台passport服務停掉模擬后台服務掛掉不可訪問的狀態,分別查看有服務熔斷和沒有服務熔斷的接口返回
有服務熔斷的返回:
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=122222

{
msg: "feign 調用后台認證服務接口(/v1/auth/login)失敗, 服務熔斷處理.",
type: "feignFallBack",
status: 400
}

http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123

{
msg: "調用后台認證接口(/passport)失敗, 服務熔斷處理.",
type: "feignFallBack",
status: 400
}

沒有服務熔斷的返回
http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Aug 27 14:13:04 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
No message available

3.6.2 服務熔斷的實現方法

  1. 代碼實現
  2. 集群實現(服務網格)

為什么會熔斷?

  1. 服務調用超時
  2. 服務異常宕機
  3. 優雅處理異常

3.6.3 調用鏈

介紹

http://skywalking.apache.org/zh/blog/2019-03-29-introduction-of-skywalking-and-simple-practice.html

使用APM分析接口調用過程
注意:

  1. 采樣率與損耗(默認是-1,每個3秒)
  2. 后台存儲保存數量h2(5000條)

服務端啟動

mkdir /root/apm && cd /root/apm
wget https://archive.apache.org/dist/skywalking/6.1.0/apache-skywalking-apm-6.1.0.tar.gz
tar zxvf apache-skywalking-apm-6.1.0.tar.gz
cd apache-skywalking-apm-bin/bin
sh startup.sh

正常啟動以后通過頁面訪問http://192.168.68.152:8080/
用戶名:admin
密碼:admin

配置文件 application.yml

#啟用ES的時候取消以下注釋
#    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
#    indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
#    indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
#    bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests
#    bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb
#    flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests
#    concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests
#    metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
#    segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}

#注釋掉h2模式配置
  h2:
    driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}
    url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}
    user: ${SW_STORAGE_H2_USER:sa}
    metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}

服務端啟動
拷貝agent目錄到需要監測的設備上,本次為單機部署,故只需要將agent目錄拷貝到指定目錄即可,當然也可以不拷貝到指定路徑,但是在啟動服務的時候需要指定agent所在的絕對路徑。

cp -r agent/ /root/springcloud/

啟動provider passport服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=provide-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar provider-passport-0.0.1-SNAPSHOT.jar

啟動服務日志可以看到加載agent的信息

DEBUG 2020-08-27 16:34:03:616 main AgentPackagePath :  The beacon class location is jar:file:/root/springcloud/agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class. 
INFO 2020-08-27 16:34:03:619 main SnifferConfigInitializer :  Config file found in /root/springcloud/agent/config/agent.config. 
...
2020-08-27 16:36:37.101  INFO 1080 --- [           main] o.s.c.a.n.registry.NacosServiceRegistry  : nacos registry, provider-passport 192.168.68.152:8086 register finished

測試訪問passport服務,查看skywalking是否可以獲取到訪問信息

for i in `seq 10000` ;do curl 192.168.68.152:8086/passport ;echo "";done

從頁面查看信息
avator

同樣的操作我們將消費者服務和網關服務也加入到skywalking的監測下
重新啟動feign服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=consumer-feign-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar consumer-feign-passport-0.0.1-SNAPSHOT.jar

重新啟動restTemplate consumer-passport服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=consumer-passport \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar consumer-passport-0.0.1-SNAPSHOT.jar

重新啟動gateway服務

java -Dspring.cloud.nacos.discovery.server-addr=192.168.68.152:8848 \
-Dspring.cloud.nacos.config.server-addr=192.168.68.152:8848 \
-javaagent:agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=gateway \
-Dskywalking.collector.backend_service=192.168.68.152:11800 \
-jar gateway-0.0.1-SNAPSHOT.jar

將上述4個服務全部重啟以后,再次在頁面查看,可以看到skywalking已經監測到這4個服務。
avator

測試服務

  1. 對feien進行模擬訪問測試
http://192.168.68.152:9000/consumer-feign-passport/v1/auth/login?token=122222
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-feign-passport/passport?token=123123 ;echo "";done
{"msg":"后台服務passport-修改配置測試","api":"/passport","type":"feignPassport","status":200}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
...
  1. 對restTemplate passport進行模擬訪問測試
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-passport/v1/auth/login?token=122222 ;echo "";done
for i in `seq 10000` ;do curl http://192.168.68.152:9000/consumer-passport/passport?token=123123 ;echo "";done 
{"msg":"demo passport restTemplate /v1/auth/login api","api":"{\"msg\":\"demo passport api\",\"api\":\"/v1/auth/consumer-passport\",\"type\":\"passportProvider\",\"status\":200}","type":"restTemplatePassport","status":200}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
{"code":403,"msg":"服務限流, 請立刻停止非法訪問"}
...

這里顯示的內容是因為我們做了服務限流。
高並發系統中有三把利器用來保護系統:緩存、降級和限流。限流的目的是為了保護系統不被大量請求沖垮,通過限制請求的速度來保護系統。在電商的秒殺活動中,限流是必不可少的一個環節。

3.7 消費者調用

feign調用
avator

restTemplate調用
avator

3.7.1 什么是Feign

Feign是模板化的http客戶端,可以幫助我們更快捷,優雅的調用http API(Rest)
Spring Cloud 對Feign進行了增強,使Feign支持Spring MVC注解,並整合了Ribbon和Eureka,從而讓Feign的使用更加方便

3.7.2 為什么需要Feign

  • 前面已經提到在消費后台服務的時候已經存下RestTemplate服務,為什么還需要Feign?
  • Feign的目的是盡量的減少資源和代碼來實現和HTTP API的連接(HTTP客戶端封裝)內網與外網調用。

3.7.3 什么是restTemplate

RestTemplate是Spring提供的額用於訪問Rest服務的客戶端,它提供了多種便捷訪問遠程http服務的方法,能夠大大提高客戶端的編寫效率。
當后台服務,比如新聞資訊服務啟動以后,用戶需要訪問,那么需要通過consumer訪問,在本實例中consumer獨立為一個服務,在實際的應用開發阿忠,會與網關集成為一個整體的服務。

3.7.4 Frign與restTemplate對比

代碼框架實現反向代理+負載均衡

比較類型 restTemplate+ribbon Feign(自帶ribbon)
可讀性,可維護性 欠佳(無法從URL直觀了解這個遠程調用過程) 極佳
開發體驗 欠佳(拼接URL) 極佳(代碼整潔)
風格一致性 一般(本地API調用和restTemplate調用的代碼風格不同) 極佳(完全一致,不點開feign的接口根本不會察覺這是一個遠程調用而非本地api調用)
性能 較好 中等(性能是restTemplate的50%左右,如果為feign配置連接池,性能可提升15%左右)
靈活性 極佳 中等(內置功能能滿足大多數項目的需求)

3.8 網關調用過程

  • 把用戶需要請求的URL地址通過路由的方式轉發到后台的服務,同時也實現鑒權的功能。
    網關位置
    avator

3.8.1 網關調用restTemplate接口過程

  • 負載均衡根據調度算法調度到網關系統
  • 網關系統接收請求以后,如果消費者(restTemplate)返回正確,那么狀態值為200,內容里面會包括provider返回的Json內容。
  • 消費者接收請求以后,如果服務提供者(Provider)返回正確,那么狀態值為200.
    avator

3.8.2 網關調用Feign接口過程

  • 負載均衡根據調度算法調度到網關系統
  • 網關系統接收請求以后,如果消費者(feign)返回正確,那么狀態值為200,內容里面會包括provider返回的Json內容。
  • 消費者接收請求以后,如果服務提供者(provider)返回正確,那么狀態值為200.
    調用過程於restTemplate相同,只是feign多封裝了一層http client。

3.9 小結

  • 所有服務注冊到注冊中心,並且每個服務可以展示多個實例
  • 注冊實例分為:臨時實例與永久實例
  • 網關:負責前台請求到后台的調用,起鑒權作用(配置文件路由/動態路由)
  • Provider:后台真正的服務提供者
  • Feign:網關通過此服務消費Provider
  • restTemplate:網關通過此服務消費Provider
  • 配置中心:在配置中心修改配置以后,可以實時通知到客戶端,並且可以回滾配置到上一個版本。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM