注冊中心Nacos
1 主流注冊中心對比
主流注冊中心對比
2 CAP實(shí)踐
AP與CP
- C是所有節(jié)點(diǎn)在同一時間看到的數(shù)據(jù)是一致的受葛;而A的定義是所有的請求都會收到響應(yīng)担映。何時選擇使用何種模式肢簿?
- 如果不需要存儲服務(wù)級別的信息且服務(wù)實(shí)例是通過nacos-client注冊拇颅,并能夠保持心跳上報(bào)胜卤,那么就可以選擇AP模式。當(dāng)前主流的服務(wù)如 Spring cloud 和 Dubbo 服務(wù),都適用于AP模式,AP模式為了服務(wù)的可能性而減弱了一致性辙喂,因此AP模式下只支持注冊臨時實(shí)例。
- 如果需要在服務(wù)級別編輯或者存儲配置信息鸠珠,那么 CP 是必須巍耗,K8S服務(wù)和DNS服務(wù)則適用于CP模式。CP模式下則支持注冊持久化實(shí)例渐排,此時則是以 Raft 協(xié)議為集群運(yùn)行模式炬太,該模式下注冊實(shí)例之前必須先注冊服務(wù),如果服務(wù)不存在驯耻,則會返回錯誤
- nacos默認(rèn)是AP亲族。curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
配置中心Nacos:
1 bootstrap.yaml配置
- Nacos同springcloud-config一樣,在項(xiàng)目初始化時可缚,要保證先從配置中心進(jìn)行配置拉取霎迫,拉取配置之后,才能保證項(xiàng)目的正常啟動帘靡。springboot中配置文件的加載是存在優(yōu)先級順序的知给,bootstrap優(yōu)先級高于application
2 配置規(guī)則
{spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
3 springcloud原生注解@RefreshScope+nacos動態(tài)刷新配置
@RestController
@RefreshScope //支持Nacos的動態(tài)刷新功能。
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;
@GetMapping("/config/info")
public String getConfigInfo() {
return configInfo;
}
}
4 配置版本回滾
nacos會記錄配置文件的歷史版本默認(rèn)保留30天描姚,此外還有一鍵回滾功能涩赢,回滾操作將觸發(fā)配置更新
5 持久化存儲到mysql
6 nacos集群配置
- 需要配置cluster.conf集群ip
- 配置每個nacos啟動端口,application.conf
- 用nginx反向代理多個nacos轩勘,生產(chǎn)環(huán)境keepalived+nginx做nginx容災(zāi)
- spring boot應(yīng)用配置nacos服務(wù)就配置nginx代理端口
服務(wù)調(diào)用與負(fù)載均衡 OpenFeign
1 open feign
- OpenFeign是Spring Cloud 在Feign的基礎(chǔ)上支持了SpringMVC的注解筒扒,如@RequesMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口绊寻,并通過動態(tài)代理的方式產(chǎn)生實(shí)現(xiàn)類花墩,實(shí)現(xiàn)類中做負(fù)載均衡并調(diào)用其他服務(wù)悬秉。經(jīng)測試spring cloud 2020.0.2nacos、open feign中已經(jīng)移除了對ribbon的依賴观游,替換成了spring cloud原生的load balance
2 調(diào)用超時熔斷
# feign 配置
feign:
sentinel:
enabled: true
okhttp:
enabled: true
httpclient:
enabled: false
client:
config:
default:
connectTimeout: 10000
readTimeout: 10000
compression:
request:
enabled: true
response:
enabled: true
3 open feign調(diào)用異常抽取
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService {
@GetMapping("/user/info/{username}")
public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
4 負(fù)載均衡
- ribbon、load balance負(fù)載均衡是進(jìn)程jvm的負(fù)載均衡(客戶端的負(fù)載均衡驮俗,不是nginx懂缕、haprox服務(wù)端的集中式負(fù)載均衡)
- load balance調(diào)用實(shí)際是用okhttp或者h(yuǎn)ttpclient包
5 設(shè)置open feign調(diào)用詳細(xì)日志
import feign.Logger;
@Configuration
public class FeignConfig{
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
# yaml
logging:
level:
# feign日志以什么級別監(jiān)控哪個接口
com.ruoyi.system.api.RemoteUserService: debug
分布式事務(wù)seata
1 核心概念
- Transaction ID XID:全局唯一的事務(wù)id
- Transaction Coordinator(TC):事務(wù)協(xié)調(diào)器,維護(hù)全局事務(wù)運(yùn)行的狀態(tài)王凑,負(fù)責(zé)協(xié)調(diào)并驅(qū)動全局事務(wù)的提交或回滾
- Transaction Manager(TM):控制全局事務(wù)的邊界搪柑,負(fù)責(zé)開啟一個全局事務(wù),并最終發(fā)起全局提交或全局回滾的決議
- Resource Manager(RM):控制分支事務(wù)索烹,負(fù)責(zé)分支注冊工碾、狀態(tài)匯報(bào)并接收事務(wù)協(xié)調(diào)的指令,驅(qū)動分支(本地)事務(wù)的提交或回滾
2 執(zhí)行流程
- TM 向 TC 申請開啟一個全局事務(wù)百姓,全局事務(wù)創(chuàng)建成功并生成一個全局唯一的 XID渊额;
- XID 在微服務(wù)調(diào)用鏈路的上下文中傳播;
- RM 向 TC 注冊分支事務(wù)垒拢,將其納入 XID 對應(yīng)全局事務(wù)的管轄旬迹;
- TM 向 TC 發(fā)起針對 XID 的全局提交或回滾決議;
- TC 調(diào)度 XID 下管轄的全部分支事務(wù)完成提交或回滾請求求类。
3 原理
- Seata 將為用戶提供了 AT奔垦、TCC、SAGA 和 XA 事務(wù)模式尸疆,開源的使用AT模式對業(yè)務(wù)代碼零侵入椿猎,只需要添加@Global Transaction
- seata在數(shù)據(jù)庫中依賴幾張表:branch_table、global_table寿弱、lock_table犯眠、undo_log
- 實(shí)例sql:update product set name = 'GTS' where name = 'TXC';
一階段
- 前提TM開啟了全局事務(wù),seata在global_table更新XID
- 解析 SQL:得到 SQL 的類型(UPDATE)症革,表(product)阔逼,條件(where name = 'TXC')等相關(guān)的信息。
- 查詢前鏡像:根據(jù)解析得到的條件信息地沮,生成查詢語句嗜浮,定位數(shù)據(jù)。select id, name, since from product where name = 'TXC';
- 執(zhí)行業(yè)務(wù) SQL:更新這條記錄的 name 為 'GTS'摩疑。
- 查詢后鏡像:根據(jù)前鏡像的結(jié)果危融,通過 主鍵 定位數(shù)據(jù)。select id, name, since from product where id = 1;
- 插入回滾日志:把前后鏡像數(shù)據(jù)以及業(yè)務(wù) SQL 相關(guān)的信息組成一條回滾日志記錄雷袋,插入到 UNDO_LOG 表中吉殃。
- 提交前辞居,向 TC 注冊分支:申請 product 表中,主鍵值等于 1 的記錄的 全局鎖 蛋勺。
- 本地事務(wù)提交:業(yè)務(wù)數(shù)據(jù)的更新和前面步驟中生成的 UNDO LOG 一并提交瓦灶。seata branch_table生成數(shù)據(jù)
- 將本地事務(wù)提交的結(jié)果上報(bào)給 TC。
二階段-回滾
- 收到 TC 的分支回滾請求抱完,開啟一個本地事務(wù)贼陶,執(zhí)行如下操作。
- 通過 XID 和 Branch ID 查找到相應(yīng)的 UNDO LOG 記錄巧娱。
- 數(shù)據(jù)校驗(yàn):拿 UNDO LOG 中的后鏡與當(dāng)前數(shù)據(jù)進(jìn)行比較碉怔,如果有不同,說明數(shù)據(jù)被當(dāng)前全局事務(wù)之- 外的動作做了修改禁添。這種情況撮胧,需要根據(jù)配置策略來做處理,詳細(xì)的說明在另外的文檔中介紹老翘。
- 根據(jù) UNDO LOG 中的前鏡像和業(yè)務(wù) SQL 的相關(guān)信息生成并執(zhí)行回滾的語句:update product set name = 'TXC' where id = 1;
- 提交本地事務(wù)芹啥。并把本地事務(wù)的執(zhí)行結(jié)果(即分支事務(wù)回滾的結(jié)果)上報(bào)給 TC。
二階段-提交
- 收到 TC 的分支提交請求铺峭,把請求放入一個異步任務(wù)的隊(duì)列中叁征,馬上返回提交成功的結(jié)果給 TC。
- 異步任務(wù)階段的分支提交請求將異步和批量地刪除相應(yīng) UNDO LOG 記錄逛薇。