Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造
前言
公司的分布式架構(gòu)是基于Alibaba Dubbo
實(shí)現(xiàn)的,微服務(wù)的相關(guān)治理也是基于Alibaba Dubbo
做的,隨著公司系統(tǒng)規(guī)模的增長(zhǎng)服務(wù)發(fā)布,服務(wù)的治理,注冊(cè)中心的壓力,硬件成本等問(wèn)題逐漸的凸顯出來(lái),尤其是服務(wù)發(fā)布和服務(wù)治理,比如多版本的發(fā)布,金絲雀發(fā)布,精細(xì)化的流量控制等,用Alibaba Dubbo
實(shí)現(xiàn)這些分布式語(yǔ)義很麻煩,在Service Mesh
架構(gòu)下,解決這些問(wèn)題都會(huì)變得容易,基于此,本篇介紹一下公司Dubbo項(xiàng)目
的Service Mesh
改造方案。
其他基礎(chǔ)架構(gòu)
除了Alibaba Dubbo
,公司使用Zookeeper
作為配置中心,分布式消息隊(duì)列rocketmq
,分布式緩存redis
,阿里云分庫(kù)分表產(chǎn)品DRDS
,阿里云關(guān)系型數(shù)據(jù)庫(kù)RDS
,這些基礎(chǔ)組件在整個(gè)Service Mesh
架構(gòu)的改造中是不變的。
Dubbo項(xiàng)目Service Mesh改造具體實(shí)現(xiàn) 基礎(chǔ)技術(shù)方案
將Dubbo
架構(gòu)改造成Service Mesh
架構(gòu)就要Dubbo
框架從項(xiàng)目中移除,我們這里將Dubbo
框架移除,并且將服務(wù)端接口全部改造成rest
接口,這就需要服務(wù)端使用新的容器發(fā)布rest
接口,所以干脆就將項(xiàng)目改造成Sping Boot Web
應(yīng)用,協(xié)議問(wèn)題沒(méi)有了,但是如何盡可能改動(dòng)小的能夠讓消費(fèi)端快速的接入Sping Boot Web
應(yīng)用的服務(wù)端就成為了難點(diǎn),由于Dubbo
項(xiàng)目API
模塊的作用與Spring Cloud Feign
模塊的作用十分相似,模塊內(nèi)都是一些interface
,需要服務(wù)端定義xxxServiceImpl
去實(shí)現(xiàn)各個(gè)interface
,然后消費(fèi)者通過(guò)Spring
依賴(lài)注入將interface
注入并使用,這就使得Dubbo
最復(fù)雜的服務(wù)間調(diào)用方式有了解決的方案。
基礎(chǔ)組件改造
- 根pom.xml引入SpringBoot parent,增加 spring-cloud-dependencies import引用
- 刪除所有
dubbo
相關(guān)引用。
這一步驟簡(jiǎn)單來(lái)說(shuō)就是將pom.xml中Dubbo的所有jar依賴(lài)全部刪除,并且引入SpringBoot parent和 spring-cloud-dependencies的引用,例如:
改造前:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.8.4</version> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <artifactId>log4j</artifactId> <groupId>log4j</groupId> </exclusion> <exclusion> <groupId>org.apache.curator</groupId> <artifactId>curator-client</artifactId> </exclusion> <exclusion> <artifactId>curator-framework</artifactId> <groupId>org.apache.curator</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> <exclusions> <exclusion> <artifactId>zookeeper</artifactId> <groupId>org.apache.zookeeper</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <!-- 移除log4j的打印框架,否則,log 4j日志不生效 --> <exclusions> <exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <artifactId>log4j</artifactId> <groupId>log4j</groupId> </exclusion> </exclusions> </dependency> </dependencies> </project>
改造后:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.3.RELEASE</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> <exclusion> <artifactId>feign-hystrix</artifactId> <groupId>io.github.openfeign</groupId> </exclusion> <exclusion> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <groupId>org.springframework.cloud</groupId> </exclusion> <exclusion> <artifactId>spring-cloud-starter-netflix-archaius</artifactId> <groupId>org.springframework.cloud</groupId> </exclusion> <exclusion> <artifactId>spring-cloud-netflix-ribbon</artifactId> <groupId>org.springframework.cloud</groupId> </exclusion> </exclusions> </dependency> </dependencies> </project>
Dubbo門(mén)面API改造
pom.xml
增加spring-cloud-starter-openfeign
引用。- 刪除所有
Dubbo
相關(guān)引用Dubbo
相關(guān)配置文件。 Dubbo
原有API
接口是標(biāo)準(zhǔn)的JAVA
接口定義,與Feign Restful
接口定義十分類(lèi)似。這里可以在原有的API
接口基礎(chǔ)上增加@FeignClient
、@RequestMapping
等注解,將一個(gè)普通的API
接口改造成一個(gè)Feign Restful
接口,后續(xù)會(huì)使用Feign
這個(gè)Restful
框架來(lái)處理服務(wù)間調(diào)用等問(wèn)題。由于Feign
本身是自帶了Ribbon
負(fù)載均衡,服務(wù)訪(fǎng)問(wèn)者經(jīng)過(guò)負(fù)載均衡后會(huì)找到服務(wù)提供者的一個(gè) IP+Port進(jìn)行調(diào)用,這與K8S Service
要求的服務(wù)名調(diào)用的方式相沖突,所以必須想辦法去掉Feign
自帶的負(fù)載均衡。好在@FeignClient
可以手工指定一個(gè)固定的調(diào)用地址,這里可以把這個(gè)地址設(shè)置成K8S Service
的name
名稱(chēng),從而實(shí)現(xiàn)了通過(guò)Feign
對(duì)K8S Service
服務(wù)名調(diào)用的能力。此部分需要每個(gè)API
接口增加注解一次,改造工作量相對(duì)可控。- 由于
Feign
要求接口使用Restful
格式,所以接口中的每個(gè)抽象方法都必須添加@RequestMapping
,@GetMapping
,@PostMapping
等注解暴露成一個(gè)Restful
資源地址。此部分改造涉及到每個(gè)API
接口的每個(gè)抽象方法,是整個(gè)方案里改動(dòng)量最大的一部分。 - 此部分整體改造工作量取決于原有的
Dubbo
項(xiàng)目包含多少個(gè)API
接口,以及每個(gè)API
包含多少個(gè)抽象方法。
改造前示例:
public interface IOdaApi { ModelsReturn<ModelsCommonResponse<ConsumptionODAResponse>> consumptionODA(ConsumptionODARequest consumptionODARequest); ModelsReturn<ModelsCommonResponse<RefundODAResponse>> refundODA(RefundODARequest refundODARequest); ModelsReturn<ModelsCommonResponse<ConsumptionODAResponse>> consumptionQueryODA( ConsumptionQueryODARequest consumptionQueryODARequest); ModelsReturn<ModelsCommonResponse<String>> repayODA(RepayODARequest repayODARequest); }
改造后示例:
@FeignClient(name = "miss-xxx-svc", url = "http://miss-xxx-svc:8080") public interface IOdaApi { @PostMapping(value = "/xxxService/consumptionODA") ModelsReturn<ModelsCommonResponse<ConsumptionODAResponse>> consumptionODA(@RequestBody ConsumptionODARequest consumptionODARequest); }
Dubbo Provider端改造
pom.xml
增加spring-boot-starter-web
、spring-cloud-starter-openfeign
等引用,同時(shí)增加SpringBoot
mainClass 標(biāo)準(zhǔn)啟動(dòng)項(xiàng)配置。刪除所有Dubbo
相關(guān)引用、Dubbo
相關(guān)配置文件。- 增加
SpringBoot
啟動(dòng)類(lèi),增加@SpringBootApplication
、@EnableFeignClients
兩個(gè)注解,配置dubbo provider服務(wù)端口號(hào)。 - xxxServiceImpl服務(wù)實(shí)現(xiàn)類(lèi)上增加
@RestController
注解,提供 consumer Restful 訪(fǎng)問(wèn)的能力。 這個(gè)需要每個(gè)服務(wù)實(shí)現(xiàn)類(lèi)都加上@RestController
注解,不要遺漏。 - 此部分大都屬于一次性改動(dòng),改造工作量相對(duì)可控。
改造后示例:
pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> ... </parent> <artifactId>MISS.xxxService</artifactId> <dependencies> <dependency> <groupId>com.xxx.xxx</groupId> <artifactId>MISS.xxxService.API</artifactId> <version>2.0.5-RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> <build> ... </build> </project>
改造后的 OdaImpl.java 代碼示例(改造前只是缺少 @RestController 注解,其他代碼完全一致):
@Slf4j @RestController public class OdaImpl implements IOdaApi { @Resource private OdaService odaService; @Override public ModelsReturn<ModelsCommonResponse<ConsumptionODAResponse>> consumptionODA(ConsumptionODARequest consumptionODARequest) { try { Validation.validate(consumptionODARequest); ... return ErrorCode.returnMsg(ErrorCode.OPSERATE_SUCCESS, odaService.consumptionODA(consumptionODARequest.getMultiIndustryInfo(),consumptionODA)); } catch (Exception e) { log.error(LogUtil.exceptionMarker(), "ODA交易異常",e); return ErrorCode.returnMsgByErrorMessage(ErrorCode.PARA_ERROR, "ODA交易異常"); } } }
Dubbo Comsumer端改造
pom.xml
增加spring-boot-starter-web
、spring-cloud-starter-openfeign
等引用,同時(shí)增加SpringBoot
mainClass 標(biāo)準(zhǔn)啟動(dòng)項(xiàng)配置。- 刪除所有
Dubbo
相關(guān)引用、Dubbo
相關(guān)配置文件。 - 增加
SpringBoot
啟動(dòng)類(lèi),增加@SpringBootApplication
、@EnableFeignClients
(需要配置 basePackages 掃描包路徑) 兩個(gè)注解,并配置dubbo consumer服務(wù)端口號(hào)。 - 此部分大都屬于一次性改動(dòng),改造工作量相對(duì)可控。
由于dubbo consumer項(xiàng)目改造與dubbo provider改造極其相似,這里不再貼出代碼示例。
總結(jié)
至此Dubbo項(xiàng)目的Service Mesh改造就已經(jīng)完成了,k8s + Istio的部署這里就不做介紹了,此方案是在我司成功落地的技術(shù)方案,并且使用次方案進(jìn)行改造的服務(wù)也具有一定規(guī)模,目前生產(chǎn)環(huán)境還沒(méi)有遇到任何問(wèn)題。
此種改造方案改動(dòng)量相對(duì)于完全的去掉dubbo而不使用feign改造的方式來(lái)說(shuō)改動(dòng)較小,如有更好的改造方案歡迎交流。
到此這篇關(guān)于Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造的文章就介紹到這了,更多相關(guān)Dubbo Service Mesh內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot詳解RocketMQ實(shí)現(xiàn)消息發(fā)送與接收流程
這篇文章主要介紹了SpringBoot整合RocketMQ實(shí)現(xiàn)消息發(fā)送和接收功能,我們使用主流的SpringBoot框架整合RocketMQ來(lái)講解,使用方便快捷,本文分步驟給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06配置JAVA環(huán)境變量中CLASSPATH變量的作用
這篇文章主要介紹了配置JAVA環(huán)境變量中CLASSPATH變量的作用,需要的朋友可以參考下2023-06-06SpringBoot整合MP通過(guò)Redis實(shí)現(xiàn)二級(jí)緩存方式
這篇文章主要介紹了SpringBoot整合MP通過(guò)Redis實(shí)現(xiàn)二級(jí)緩存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01SpringBoot 整合WebSocket 前端 uniapp 訪(fǎng)問(wèn)的詳細(xì)方法
這篇文章主要介紹了SpringBoot 整合WebSocket 前端 uniapp 訪(fǎng)問(wèn)的詳細(xì)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09Java Semaphore實(shí)現(xiàn)高并發(fā)場(chǎng)景下的流量控制
在java開(kāi)發(fā)的工作中是否會(huì)出現(xiàn)這樣的場(chǎng)景,你需要實(shí)現(xiàn)一些異步運(yùn)行的任務(wù),該任務(wù)可能存在消耗大量?jī)?nèi)存的情況,所以需要對(duì)任務(wù)進(jìn)行并發(fā)控制。本文將介紹通過(guò)Semaphore類(lèi)優(yōu)雅的實(shí)現(xiàn)并發(fā)控制,感興趣的可以了解一下2021-12-12詳解在springboot中使用Mybatis Generator的兩種方式
這篇文章主要介紹了詳解在springboot中使用Mybatis Generator的兩種方式,本文將介紹到在springboot的項(xiàng)目中如何去配置和使用MBG以及MBG生成代碼的兩種方式,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-11-11