Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造
前言
公司的分布式架構(gòu)是基于Alibaba Dubbo實現(xiàn)的,微服務(wù)的相關(guān)治理也是基于Alibaba Dubbo做的,隨著公司系統(tǒng)規(guī)模的增長服務(wù)發(fā)布,服務(wù)的治理,注冊中心的壓力,硬件成本等問題逐漸的凸顯出來,尤其是服務(wù)發(fā)布和服務(wù)治理,比如多版本的發(fā)布,金絲雀發(fā)布,精細化的流量控制等,用Alibaba Dubbo實現(xiàn)這些分布式語義很麻煩,在Service Mesh架構(gòu)下,解決這些問題都會變得容易,基于此,本篇介紹一下公司Dubbo項目的Service Mesh改造方案。
其他基礎(chǔ)架構(gòu)
除了Alibaba Dubbo,公司使用Zookeeper作為配置中心,分布式消息隊列rocketmq,分布式緩存redis,阿里云分庫分表產(chǎn)品DRDS,阿里云關(guān)系型數(shù)據(jù)庫RDS,這些基礎(chǔ)組件在整個Service Mesh架構(gòu)的改造中是不變的。
Dubbo項目Service Mesh改造具體實現(xiàn) 基礎(chǔ)技術(shù)方案
將Dubbo架構(gòu)改造成Service Mesh架構(gòu)就要Dubbo框架從項目中移除,我們這里將Dubbo框架移除,并且將服務(wù)端接口全部改造成rest接口,這就需要服務(wù)端使用新的容器發(fā)布rest接口,所以干脆就將項目改造成Sping Boot Web應(yīng)用,協(xié)議問題沒有了,但是如何盡可能改動小的能夠讓消費端快速的接入Sping Boot Web應(yīng)用的服務(wù)端就成為了難點,由于Dubbo項目API模塊的作用與Spring Cloud Feign模塊的作用十分相似,模塊內(nèi)都是一些interface,需要服務(wù)端定義xxxServiceImpl去實現(xiàn)各個interface,然后消費者通過Spring依賴注入將interface注入并使用,這就使得Dubbo最復(fù)雜的服務(wù)間調(diào)用方式有了解決的方案。
基礎(chǔ)組件改造
- 根pom.xml引入SpringBoot parent,增加 spring-cloud-dependencies import引用
- 刪除所有
dubbo相關(guān)引用。
這一步驟簡單來說就是將pom.xml中Dubbo的所有jar依賴全部刪除,并且引入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門面API改造
pom.xml增加spring-cloud-starter-openfeign引用。- 刪除所有
Dubbo相關(guān)引用Dubbo相關(guān)配置文件。 Dubbo原有API接口是標(biāo)準(zhǔn)的JAVA接口定義,與Feign Restful接口定義十分類似。這里可以在原有的API接口基礎(chǔ)上增加@FeignClient、@RequestMapping等注解,將一個普通的API接口改造成一個Feign Restful接口,后續(xù)會使用Feign這個Restful框架來處理服務(wù)間調(diào)用等問題。由于Feign本身是自帶了Ribbon負載均衡,服務(wù)訪問者經(jīng)過負載均衡后會找到服務(wù)提供者的一個 IP+Port進行調(diào)用,這與K8S Service要求的服務(wù)名調(diào)用的方式相沖突,所以必須想辦法去掉Feign自帶的負載均衡。好在@FeignClient可以手工指定一個固定的調(diào)用地址,這里可以把這個地址設(shè)置成K8S Service的name名稱,從而實現(xiàn)了通過Feign對K8S Service服務(wù)名調(diào)用的能力。此部分需要每個API接口增加注解一次,改造工作量相對可控。- 由于
Feign要求接口使用Restful格式,所以接口中的每個抽象方法都必須添加@RequestMapping,@GetMapping,@PostMapping等注解暴露成一個Restful資源地址。此部分改造涉及到每個API接口的每個抽象方法,是整個方案里改動量最大的一部分。 - 此部分整體改造工作量取決于原有的
Dubbo項目包含多少個API接口,以及每個API包含多少個抽象方法。
改造前示例:
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等引用,同時增加SpringBootmainClass 標(biāo)準(zhǔn)啟動項配置。刪除所有Dubbo相關(guān)引用、Dubbo相關(guān)配置文件。- 增加
SpringBoot啟動類,增加@SpringBootApplication、@EnableFeignClients兩個注解,配置dubbo provider服務(wù)端口號。 - xxxServiceImpl服務(wù)實現(xiàn)類上增加
@RestController注解,提供 consumer Restful 訪問的能力。 這個需要每個服務(wù)實現(xiàn)類都加上@RestController注解,不要遺漏。 - 此部分大都屬于一次性改動,改造工作量相對可控。
改造后示例:
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等引用,同時增加SpringBootmainClass 標(biāo)準(zhǔn)啟動項配置。- 刪除所有
Dubbo相關(guān)引用、Dubbo相關(guān)配置文件。 - 增加
SpringBoot啟動類,增加@SpringBootApplication、@EnableFeignClients(需要配置 basePackages 掃描包路徑) 兩個注解,并配置dubbo consumer服務(wù)端口號。 - 此部分大都屬于一次性改動,改造工作量相對可控。
由于dubbo consumer項目改造與dubbo provider改造極其相似,這里不再貼出代碼示例。
總結(jié)
至此Dubbo項目的Service Mesh改造就已經(jīng)完成了,k8s + Istio的部署這里就不做介紹了,此方案是在我司成功落地的技術(shù)方案,并且使用次方案進行改造的服務(wù)也具有一定規(guī)模,目前生產(chǎn)環(huán)境還沒有遇到任何問題。
此種改造方案改動量相對于完全的去掉dubbo而不使用feign改造的方式來說改動較小,如有更好的改造方案歡迎交流。
到此這篇關(guān)于Dubbo Service Mesh基礎(chǔ)架構(gòu)組件改造的文章就介紹到這了,更多相關(guān)Dubbo Service Mesh內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot詳解RocketMQ實現(xiàn)消息發(fā)送與接收流程
這篇文章主要介紹了SpringBoot整合RocketMQ實現(xiàn)消息發(fā)送和接收功能,我們使用主流的SpringBoot框架整合RocketMQ來講解,使用方便快捷,本文分步驟給大家介紹的非常詳細,需要的朋友可以參考下2022-06-06
配置JAVA環(huán)境變量中CLASSPATH變量的作用
這篇文章主要介紹了配置JAVA環(huán)境變量中CLASSPATH變量的作用,需要的朋友可以參考下2023-06-06
SpringBoot整合MP通過Redis實現(xiàn)二級緩存方式
這篇文章主要介紹了SpringBoot整合MP通過Redis實現(xiàn)二級緩存方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
SpringBoot 整合WebSocket 前端 uniapp 訪問的詳細方法
這篇文章主要介紹了SpringBoot 整合WebSocket 前端 uniapp 訪問的詳細方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
Java Semaphore實現(xiàn)高并發(fā)場景下的流量控制
在java開發(fā)的工作中是否會出現(xiàn)這樣的場景,你需要實現(xiàn)一些異步運行的任務(wù),該任務(wù)可能存在消耗大量內(nèi)存的情況,所以需要對任務(wù)進行并發(fā)控制。本文將介紹通過Semaphore類優(yōu)雅的實現(xiàn)并發(fā)控制,感興趣的可以了解一下2021-12-12
詳解在springboot中使用Mybatis Generator的兩種方式
這篇文章主要介紹了詳解在springboot中使用Mybatis Generator的兩種方式,本文將介紹到在springboot的項目中如何去配置和使用MBG以及MBG生成代碼的兩種方式,非常具有實用價值,需要的朋友可以參考下2018-11-11

