問題背景
問題的現象是生產的服務在部署到consul上面之後,一直往下掉
開始解決
首先介紹下生產的consul部署方式爲 集羣部署 3 server 3 client
3個server節點 3個 client節點
|
域名
|
IP
|
|
server1
|
k8sm1
|
10.23.111.17
|
|
server2
|
k8sm2
|
10.23.111.44
|
|
server3
|
k8sm3
|
10.23.111.45
|
|
client1
|
k8sn4
|
10.23.111.21
|
|
client2
|
k8sn5
|
10.23.111.22
|
|
client3
|
k8sn6
|
10.23.111.51
|
|
以下爲consul地址: https://consul-ccp.nanopay.mx/ui/
1、查看所有的機器情況
登陸任意一臺機器執行:
1、能看到所有集羣的機器
2、查看集羣主和從機器
consul operator raft list-peers
3、查看consul版本
[ec2-user@ccp-prod-k8m1 ~]$ consul version
Consul v1.12.3
Revision 2308c75e
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
如果按照原先的方式部署服務,會出現不穩定的情況;
2、自己手工註冊服務
因爲我們目前註冊地址是 dbproxies;
我們可以看看這個機器的IP:
telnet dbproxies 8500
root@dev-fms-service-impl-prod-54fb8875d4-9gbsp:/logs# telnet dbproxies 8500
Trying 10.68.244.75...
Connected to dbproxies.ccp.svc.cluster.local.
Escape character is '^]'.
可以自己進入某個生產服務的pod 進行手工註冊:
比如進入 ccp-gateway-bootstrap的生產的pod然後執行:
curl -s -X PUT -d '{"id":"yfq-acm-service-impl-8002-10-23-111-17-1174221935015174264","name":"2yfq-acm-service-impl","address":"172.20.187.129","port":9195,"tags":["yfq-faceservice"],"checks":[{"http":"http://10.23.111.17:8500/ui/","interval":"15s"}]}' http://dbproxies:8500/v1/agent/service/register
注意裏面的check的path(10.23.111.17:8500) 一定要真實可用,否則服務註冊會不成功;
然後看看 consul的服務是否正常
當然註冊完了,
先使用命令看下:
curl dbproxies:8500/v1/agent/services
也可以查看縮略版本的:
curl dbproxies:8500/v1/catalog/services
也可以刪除某個服務:比如acm-service-impl
curl -X PUT http://dbproxies:8500/v1/agent/service/deregister/a00-acm-service-impl-8002-10-23-111-17-7718219848784511644
不要着急,需要等一會兒才能註冊上
在這裏重啓:
在ui裏面看到服務又回來了:
如果註冊不上需要進入pod看下日誌:出現這個,說明註冊成功
我發現刪除有時候會失敗,不着急,下面的兩個方法都可以 先使用 接口 v1/agent/services查詢一下,不穩定,有時候能查到,有時候查不到,多執行幾次就可以了,等到查到了,然後執行刪除的命令;
1、這樣刪除
curl -X PUT http://dbproxies:8500/v1/agent/service/deregister/a00-fms-service-impl-8012-172-20-123-22
2、這樣刪除
curl -X PUT http://10.23.111.17:8500/v1/agent/service/deregister/a00-fms-service-impl-8012-172-20-123-22
,
刪除dbproxies註冊的服務:
使用 10.68.244.75 可以把集羣刪掉;
curl -X PUT http://10.68.244.75:8500/v1/agent/service/deregister/test-acm-service-impl-8002-10-23-111-17-1
這樣找到了自己註冊的服務:
root@dev-acm-web-prod-dc6477dd6-5kmmm:/# telnet dbproxies 8500
Trying 10.68.244.75...
Connected to dbproxies.ccp.svc.cluster.local.
Escape character is '^]'.
curl 10.68.244.75:8500/v1/agent/services
4、可以查看詳細的接口信息
在pod裏面執行:
http://dbproxies:8500/v1/agent/services 詳細信息
http://dbproxies:8500/v1/catalog/services -->這個是縮略的比較少,統計信息
5、正確刪除姿勢:
先查詢:
curl dbproxies:8500/v1/agent/services
有時候是空的,有時候又有值;
等到查詢到值的時候,執行:
curl -X PUT http://10.68.244.75:8500/v1/agent/service/deregister/a00-acm-service-impl-8002-dbproxies-3450823776658351514
就可以了: 如下圖所示,剛開始 查詢是空的,後來查詢就有值了,然後執行刪除就可以了;
6、查看健康狀態,多執行幾次,第一次可能是空的
參考:https://blog.csdn.net/u010173095/article/details/88569651
curl -X GET http://dbproxies:8500/v1/agent/checks
ttl健康檢查有問題:https://www.cnblogs.com/duanxz/p/9662862.html
預發上面 也沒有ttl健康檢查;
通過比對自己註冊的服務和當前生產註冊的服務發現一個問題,生產註冊的服務類型是ttl,但是手動註冊的服務類型是http,ttl一直有問題,但是http卻很正常;
例如:
生產註冊的:
自己手動註冊的:
問題很明顯了,我們的使用了ttl模式註冊有問題,但是使用http模式卻沒問題;
所以我們們首先要搞清楚 ttl和http模式到底是什麼健康檢查,是怎麼執行的
和https://juejin.cn/post/6878443985703010312
裏面寫的很清楚,consul的健康檢查分爲四個類型:Check必須是Script、HTTP、TCP、TTL四種類型中的一種
但是我們使用了 springCloudConsul所以目前有兩種類型:
1、http +interval
2、ttl類型(Time To live)
裏面寫的很清楚了,當spring.cloud.consul.discovery.heartbeat.enabled=true 代表使用ttl類型
如果爲false代表爲http+interval類型;
如果我們使用了ttl類型則要提供 一個定時任務schedule 定時上報到一個url上面,提供 ttl時間
spring.cloud.consul.host=122.8.189.23
#spring.cloud.consul.host=94.74.64.71
#spring.cloud.consul.host=94.74.68.42
spring.cloud.consul.service-registry.auto-registration.enabled=true
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.health-check-critical-timeout=30s
spring.cloud.consul.discovery.heartbeat.enabled=true
spring.cloud.consul.discovery.heartbeat.ttl=10
spring.cloud.consul.discovery.enabled=true
spring.cloud.consul.discovery.register=true
spring.cloud.consul.discovery.port=${server.port}
spring.cloud.consul.discovery.preferIpAddress=true
spring.cloud.consul.discovery.instance-id=${cn.sunline.kite.instanceId}
spring.cloud.consul.discovery.metadata.dcn=${cn.sunline.kite.dcn}
spring.cloud.consul.discovery.metadata.artifactId=${cn.sunline.kite.artifactId}
spring.cloud.consul.discovery.metadata.gourpId=${cn.sunline.kite.groupId}
spring.cloud.consul.discovery.tags=${spring.profiles.active}
spring.cloud.consul.discovery.default-query-tag=${spring.profiles.active}
上面這是我們目前的配置;
當我們使用spring.cloud.consul.discovery.enabled=true的時候代表使用了ttl模式,
則spring.cloud.consul.discovery.heartbeat.ttl=10 這個參數會生效;其他參數自動變成空;
當spring.cloud.consul.discovery.enabled=false的時候代表使用了http模式,
spring.cloud.consul.discovery.heartbeat.ttl 你無論填上什麼值,在追蹤日誌的時候都是空;
然後會使用:
spring.cloud.consul.discovery.health-check-interval =10(可以新增這個變量)
spring.cloud.consul.discovery.health-check-path = /actuator/health(可以新增這個變量)
我上面寫的是默認值,也就是說如果你不添加這兩個變量,會默認走這兩個值;
###consul###
spring.cloud.consul.host=10.10.200.15
spring.cloud.consul.service-registry.auto-registration.enabled=true
spring.cloud.consul.port=8500
#定義 consul 健康檢查路徑
spring.cloud.consul.discovery.health-check-path=/actuator/health
# # 執行監控檢查的頻率
spring.cloud.consul.discovery.health-check-interval=10s
spring.cloud.consul.discovery.health-check-critical-timeout=30s
spring.cloud.consul.discovery.heartbeat.enabled=true
spring.cloud.consul.discovery.heartbeat.ttl=10
spring.cloud.consul.discovery.enabled=true
spring.cloud.consul.discovery.register=true
spring.cloud.consul.discovery.port=${server.port}
spring.cloud.consul.discovery.preferIpAddress=true
spring.cloud.consul.discovery.instance-id=${cn.sunline.kite.instanceId}
spring.cloud.consul.discovery.metadata.dcn=${cn.sunline.kite.dcn}
spring.cloud.consul.discovery.metadata.artifactId=${cn.sunline.kite.artifactId}
spring.cloud.consul.discovery.metadata.gourpId=${cn.sunline.kite.groupId}
spring.cloud.consul.discovery.tags=${spring.profiles.active}
spring.cloud.consul.discovery.default-query-tag=${spring.profiles.active}
###consul###
可以查看日誌(acm-service-impl的):
(a)這是http模式的日誌:注意http模式即使你配置了ttl也是空;
[2022-08-29 09:36:46:932] [INFO ] [main] [ConsulServiceRegistry] Registering
service with consul: NewService{id='a00-acm-service-impl-8002-dbproxies-1853363605372601210',
name='a00-acm-service-impl', tags=[nova], address='172.20.26.165',
meta={dcn=a00, artifactId=acm-service-impl, gourpId=cn.sunline.acm, secure=false}, port=8002,
enableTagOverride=null, check=Check{script='null', dockerContainerID='null',
shell='null', interval='10s', ttl='null', http='http://172.20.26.165:8002/actuator/health',
method='null', header={}, tcp='null', timeout='null', deregisterCriticalServiceAfter='30s', t
lsSkipVerify=null, status='null', grpc='null', grpcUseTLS=null}, checks=null}
(b) 這是ttl模式的日誌:注意ttl這時候已經生效了;
結論
改動很簡單,直接將
spring.cloud.consul.discovery.heartbeat.enabled=false
也就是 從ttl模式改到 http模式就可以了;
他們的區別是:
ttl模式是 提供一個定時任務,主動上傳到consul的接口,是推的模式;
http模式 是提供一個監控檢查的url, consul主動去輪訓檢查,是拉的模式;
你在執行 dbproxies:8500/v1/agent/checks的時候,會發現;生產 有這個ttl和http的問題,
但是預發沒有這個問題,預發這個type是空的,因爲預發是單機部署,不存在這個問題;