
大家好,我是冰河~~
目前,我們自己手寫的RPC框架已經完成了整體設計、服務提供者的實現、服務消費者的實現、注冊中心的實現、負載均衡的實現、SPI擴展序列化機制、SPI擴展動態代理機制、SPI擴展反射機制、SPI擴展負載均衡策略、SPI擴展增強型負載均衡策略、SPI擴展實現注冊中心、心跳機制、增強型心跳機制、重試機制、整合Spring、整合SpringBoot和整合Docker等篇章,共計80+篇文章。
本節,我們就基于《SpringCloud Alibaba》專欄的源碼整合自己手寫的bhrpc框架,替換掉原有項目中使用的Fegin框架。
1、新增shop-service-api工程
(1)新增shop-service-api工程
在父工程shop-springcloud-alibaba下新建shop-service-api子工程,并在shop-service-api子工程的pom.xml文件中添加如下配置。
<dependencies>
<dependency>
<groupId>io.binghe.shop</groupId>
<artifactId>shop-bean</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
shop-service-api子工程的作用就是將shop-user工程中的UserService接口和shop-product工程中的ProductService接口單獨分離出來,便于后續整合bhrpc框架。
(2)新增UserService接口
UserService接口的源碼詳見:shop-service-api工程下的io.binghe.shop.service.UserService,如下所示。
public interface UserService {
/**
* 根據id獲取用戶信息
*/
User getUserById(Long userId);
}
刪除shop-user工程下的io.binghe.shop.user.service.UserService接口,并修改shop-user工程中的報錯信息,將報錯類中原本依賴io.binghe.shop.user.service.UserService接口修改成依賴io.binghe.shop.service.UserService接口。
(3)新增ProductService接口
ProductService接口的源碼詳見:shop-service-api工程下的io.binghe.shop.service.ProductService,如下所示。
public interface ProductService {
/**
* 根據商品id獲取商品信息
*/
Product getProductById(Long pid);
/**
* 扣減商品庫存
*/
int updateProductStockById(Integer count, Long id);
}
刪除shop-product工程下的io.binghe.shop.product.service.ProductService接口,并修改shop-product工程中的報錯信息,將報錯類中原本依賴io.binghe.shop.product.service.ProductService接口修改成依賴io.binghe.shop.service.ProductService接口。
2、改造shop-user工程
shop-user工程對應bhrpc框架的服務提供者角色。
(1)添加pom.xml依賴
shop-user工程作為bhrpc框架的服務提供者,在pom.xml需要添加如下依賴。
<dependency>
<groupId>io.binghe.rpc</groupId>
<artifactId>bhrpc-spring-boot-starter-provider</artifactId>
<version>${bhrpc.version}</version>
</dependency>
<dependency>
<groupId>io.binghe.shop</groupId>
<artifactId>shop-service-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
(2)修改UserServiceImpl類
UserServiceImpl類的源碼詳見:shop-user工程下的io.binghe.shop.user.service.impl.UserServiceImpl,需要將UserServiceImpl類上標注的Spring中的@Service注解,替換成bhrpc框架中的@RpcService注解,修改后的源碼如下所示。
@RpcService(interfaceClass = UserService.class, version = "1.0.0", group = "binghe")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getUserById(Long userId) {
return userMapper.selectById(userId);
}
}
可以看到,在UserServiceImpl類上標注了bhrpc框架中的@RpcService注解,并且指定了interfaceClass、version和group屬性。
(3)修改UserStarter類
UserStarter類的源碼詳見:shop-user工程下的io.binghe.shop.UserStarter,主要是在UserStarter類上添加@ComponentScan注解,修改后的源碼如下所示。
@SpringBootApplication
@ComponentScan(basePackages = {"io.binghe.shop", "io.binghe.rpc"})
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(value = { "io.binghe.shop.user.mapper" })
@EnableDiscoveryClient
@EnableAsync
public class UserStarter {
public static void main(String[] args){
SpringApplication.run(UserStarter.class, args);
}
}
可以看到,在UserStarter類上標注了@ComponentScan注解,并指定了掃描的包路徑為io.binghe.shop和io.binghe.rpc,使其既能夠掃描到微服務項目中包下的類,也能夠掃描到bhrpc框架包下的類。
(4)添加配置
由于項目使用了Nacos作為配置中心,所以,需要在Nacos添加shop-user工程作為服務提供者的配置,登錄Nacos管理端,找到shop-user工程的配置,如下所示。

shop-user工程的配置
點擊編輯按鈕,在原有配置的基礎上,添加如下配置信息。
bhrpc:
binghe:
provider:
# rpc server
serverAddress: 127.0.0.1:20880
# serverRegistryAddress
serverRegistryAddress: 127.0.0.1:20880
# zookeeper server
registryAddress: 127.0.0.1:2181
# registry center type
registryType: zookeeper
#registry loadbalance type
registryLoadBalanceType: zkconsistenthash
# reflect type
reflectType: cglib
# heartbeatInterval
heartbeatInterval: 30000
可以看到,配置的內容都是bhrpc框架的服務提供者啟動時,需要讀取的一些參數信息。配置完成后,點擊發布按鈕進行發布。
至此,shop-user工程改造完成,是不是非常簡單呢?我們自己手寫的bhrpc框架整合SpringCloud Alibaba項目就是這么簡單。
3、改造shop-product工程
shop-product工程對應bhrpc框架的服務提供者角色。改造shop-product工程的步驟與改造shop-user工程的步驟基本相同。
(1)添加pom.xml依賴
shop-product工程同樣作為bhrpc框架的服務提供者,在pom.xml需要添加如下依賴。
<dependency>
<groupId>io.binghe.rpc</groupId>
<artifactId>bhrpc-spring-boot-starter-provider</artifactId>
<version>${bhrpc.version}</version>
</dependency>
<dependency>
<groupId>io.binghe.shop</groupId>
<artifactId>shop-service-api</artifactId>
<version>${project.version}</version>
</dependency>
(2)修改ProductServiceImpl類
ProductServiceImpl類的源碼詳見:shop-product工程下的io.binghe.shop.product.service.impl.ProductServiceImpl,需要將ProductServiceImpl類上標注的Spring中的@Service注解,替換成bhrpc框架中的@RpcService注解,修改后的源碼如下所示。
@RpcService(interfaceClass = ProductService.class, version = "1.0.0", group = "binghe")
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductMapper productMapper;
@Override
public Product getProductById(Long pid) {
return productMapper.selectById(pid);
}
@Override
public int updateProductStockById(Integer count, Long id) {
return productMapper.updateProductStockById(count, id);
}
}
可以看到,在ProductServiceImpl類上標注了bhrpc框架中的@RpcService注解,并且指定了interfaceClass、version和group屬性。
(3)修改ProductStarter類
ProductStarter類的源碼詳見:shop-product工程下的io.binghe.shop.ProductStarter,主要是在ProductStarter類上添加@ComponentScan注解,修改后的源碼如下所示。
@SpringBootApplication
@ComponentScan(basePackages = {"io.binghe.shop", "io.binghe.rpc"})
@MapperScan(value = { "io.binghe.shop.product.mapper" })
@EnableTransactionManagement(proxyTargetClass = true)
@EnableDiscoveryClient
public class ProductStarter {
public static void main(String[] args){
SpringApplication.run(ProductStarter.class, args);
}
}
可以看到,在ProductStarter類上標注了@ComponentScan注解,并指定了掃描的包路徑為io.binghe.shop和io.binghe.rpc,使其既能夠掃描到微服務項目中包下的類,也能夠掃描到bhrpc框架包下的類。
(4)添加配置
由于項目使用了Nacos作為配置中心,所以,需要在Nacos添加shop-product工程作為服務提供者的配置,登錄Nacos管理端,找到shop-product工程的配置,如下所示。

shop-product工程的配置
點擊編輯按鈕,在原有配置的基礎上,添加如下配置信息。
bhrpc:
binghe:
provider:
# rpc server
serverAddress: 127.0.0.1:20881
# serverRegistryAddress
serverRegistryAddress: 127.0.0.1:20881
# zookeeper server
registryAddress: 127.0.0.1:2181
# registry center type
registryType: zookeeper
#registry loadbalance type
registryLoadBalanceType: zkconsistenthash
# reflect type
reflectType: cglib
# heartbeatInterval
heartbeatInterval: 30000
可以看到,配置的內容也都是bhrpc框架的服務提供者啟動時,需要讀取的一些參數信息。配置完成后,點擊發布按鈕進行發布。
至此,shop-product工程改造完成,也是非常簡單的。
4、改造shop-order工程
shop-order工程對應bhrpc框架的服務消費者角色。
(1)添加pom.xml依賴
shop-order工程作為bhrpc框架的服務消費者,在pom.xml需要添加如下依賴。
<dependency>
<groupId>io.binghe.rpc</groupId>
<artifactId>bhrpc-spring-boot-starter-consumer</artifactId>
<version>${bhrpc.version}</version>
</dependency>
<dependency>
<groupId>io.binghe.shop</groupId>
<artifactId>shop-service-api</artifactId>
<version>${project.version}</version>
</dependency>
(2)新增OrderServiceV9Impl類
為了不影響整體項目原有的邏輯,復制OrderServiceV8Impl類的代碼,新增成為OrderServiceV9Impl類,OrderServiceV9Impl類的源碼詳見:shop-order工程下的io.binghe.shop.order.service.impl.OrderServiceV9Impl,類框架代碼如下所示。
@Slf4j
@Service("orderServiceV9")
public class OrderServiceV9Impl implements OrderService {
}
(3)改造OrderServiceV9Impl類
將OrderServiceV9Impl類中,原本userService和productService成員變量上標注的Spring中的@Autowired注解替換成bhrpc框架中的@RpcReference注解,替換后的源碼如下所示。
@RpcReference(registryType = "zookeeper", registryAddress = "127.0.0.1:2181", loadBalanceType = "zkconsistenthash", version = "1.0.0", group = "binghe", serializationType = "protostuff", proxy = "cglib", timeout = 30000, async = false)
private UserService userService;
@RpcReference(registryType = "zookeeper", registryAddress = "127.0.0.1:2181", loadBalanceType = "zkconsistenthash", version = "1.0.0", group = "binghe", serializationType = "protostuff", proxy = "cglib", timeout = 30000, async = false)
private ProductService productService;
可以看到,userService和productService成員變量上標注了bhrpc框架中的@RpcReference注解,并且配置了服務消費者啟動時需要的一些參數信息。
注意:需要將OrderServiceV9Impl類中的UserService改成引用io.binghe.shop.service.UserService接口,將ProductService改成引用io.binghe.shop.service.ProductService接口,修改OrderServiceV9Impl類中的一些報錯信息。
(4)修改OrderStarter類
OrderStarter類的源碼詳見:shop-order工程下的io.binghe.shop.OrderStarter,主要是在OrderStarter類上添加@ComponentScan注解,修改后的源碼如下所示。
@SpringBootApplication
@ComponentScan(basePackages = {"io.binghe.shop", "io.binghe.rpc"})
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(value = { "io.binghe.shop.order.mapper" })
@EnableDiscoveryClient
@EnableFeignClients
public class OrderStarter {
public static void main(String[] args){
SpringApplication.run(OrderStarter.class, args);
}
}
可以看到,在OrderStarter類上標注了@ComponentScan注解,并指定了掃描的包路徑為io.binghe.shop和io.binghe.rpc,使其既能夠掃描到微服務項目中包下的類,也能夠掃描到bhrpc框架包下的類。
(5)添加配置
由于項目使用了Nacos作為配置中心,所以,需要在Nacos添加shop-order工程作為服務消費者的配置,登錄Nacos管理端,找到shop-order工程的配置,如下所示。

shop-order工程的配置
點擊編輯按鈕,在原有配置的基礎上,添加如下配置信息。
bhrpc:
binghe:
consumer:
# zookeeper server
registryAddress: 127.0.0.1:2181
# registry center type
registryType: zookeeper
# registry loadbalance type
loadBalanceType: zkconsistenthash
# proxy type
proxy: cglib
# version
version: 1.0.0
# group
group: binghe
# zkconsistenthash
serializationType: zkconsistenthash
# timeout
timeout: 30000
# async
async: false
# oneway
oneway: false
# heartbeatInterval
heartbeatInterval: 15000
# retryInterval
retryInterval: 1000
# retryTimes
retryTimes: 3
可以看到,配置的內容都是bhrpc框架的服務消費者啟動時,需要讀取的一些參數信息。配置完成后,點擊發布按鈕進行發布。
(6)修改OrderController類
OrderController類的源碼詳見:shop-order工程下的io.binghe.shop.order.controller.OrderController,主要是將OrderController類中使用@Qualifier注解標識的orderServiceV8修改成orderServiceV9,如下所示。
@Autowired
@Qualifier(value = "orderServiceV9")
private OrderService orderService;
至此,shop-order工程改造完成,也是非常簡單的。
目前,在SpringCloud Alibaba項目中整合我們自己手寫的RPC框架就完成了,是不是非常簡單呢?沒錯,我們自己手寫的bhrpc框架整合SpringCloud Alibaba項目就是這么簡單!
5、測試?
整合完不測試下怎么行?
(1)、啟動服務
分別啟動Nacos、RocketMQ、Sentinel、ZipKin、Seata和Zookeeper服務,對應服務的版本在源碼的README.md文件中有說明。
(2)、啟動工程
按順序分別啟動shop-user工程、shop-product工程、shop-order工程和shop-gateway工程。
輸出如下信息,沒有報錯,說明bhrpc框架監聽的是20880端口,表示啟動成功。
i.b.r.p.common.server.base.BaseServer : Server started on port 20880
輸出如下信息,沒有報錯,說明bhrpc框架監聽的是20881端口,表示啟動成功。
i.b.r.p.common.server.base.BaseServer : Server started on port 20881
輸出如下信息,沒有報錯,說明啟動成功。
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '/order'
輸出如下信息,沒有報錯,說明啟動成功。
io.binghe.shop.GatewayStarter : Started GatewayStarter in 9.604 seconds (JVM running for 10.964)
(3)、查詢數據表數據
(1)打開cmd終端,進入MySQL命令行,并進入shop商城數據庫,如下所示。
C:\Users\binghe>mysql -uroot -p
Enter password: ****
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 5.7.35 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use shop;
Database changed
(2)查看商品數據表,如下所示。
mysql> select * from t_product;
+------+------------+-------------+-------------+
| id | t_pro_name | t_pro_price | t_pro_stock |
+------+------------+-------------+-------------+
| 1001 | 華為 | 2399.00 | 100 |
| 1002 | 小米 | 1999.00 | 100 |
| 1003 | iphone | 4999.00 | 100 |
+------+------------+-------------+-------------+
3 rows in set (0.00 sec)
這里,我們以id為1001的商品為例,此時發現商品的庫存為100。
(3)查詢訂單數據表,如下所示。
mysql> select * from t_order;
Empty set (0.00 sec)
可以發現訂單數據表為空。
(4)查詢訂單條目數據表,如下所示。
mysql> select * from t_order_item;
Empty set (0.00 sec)
可以看到,訂單條目數據表為空。
(4)、訪問項目
打開瀏覽器訪問http://localhost:10002/server-order/order/submit_order?userId=1001&productId=1001&count=1,如下所示。

訪問結果
可以看到,項目返回的結果為success,表示項目執行成功。
5、再次查看數據表數據
(1)查看商品數據表,如下所示。
mysql> select * from t_product;
+------+------------+-------------+-------------+
| id | t_pro_name | t_pro_price | t_pro_stock |
+------+------------+-------------+-------------+
| 1001 | 華為 | 2399.00 | 99 |
| 1002 | 小米 | 1999.00 | 100 |
| 1003 | iphone | 4999.00 | 100 |
+------+------------+-------------+-------------+
3 rows in set (0.00 sec)
這里,id為1001的商品庫存為99,說明庫存已經減少了1。
(2)查詢訂單數據表,如下所示。
mysql> select * from t_order;
+-------------------+-----------+-------------+-------------+-----------+---------------+
| id | t_user_id | t_user_name | t_phone | t_address | t_total_price |
+-------------------+-----------+-------------+-------------+-----------+---------------+
| 96829539832958976 | 1001 | binghe | 13212345678 | 北京 | 2399.00 |
+-------------------+-----------+-------------+-------------+-----------+---------------+
1 row in set (0.00 sec)
可以看到,在t_order表中新增了一張訂單數據表,訂單的總金額為2399.00元。
(3)查詢訂單條目數據表,如下所示。
mysql> select * from t_order_item;
+-------------------+-------------------+----------+------------+-------------+----------+
| id | t_order_id | t_pro_id | t_pro_name | t_pro_price | t_number |
+-------------------+-------------------+----------+------------+-------------+----------+
| 96829541082861568 | 96829539832958976 | 1001 | 華為 | 2399.00 | 1 |
+-------------------+-------------------+----------+------------+-------------+----------+
1 row in set (0.00 sec)
可以看到,訂單條目數據表中條了一條訂單條目數據,商品的id為1001,商品名稱為華為,商品的價格為2399.00,下單的商品數量為1。
根據測試結果可以看出,我們已經正確在SpringCloud Alibaba項目中整合了我們自己手寫的bhrpc框架。
6、總結?
實現了功能不總結下怎么行?
在完成整合Spring的篇章后,我們又開啟了整合SpringBoot的篇章,首先,我們完成了服務提供者整合SpringBoot的功能,并基于SpringBoot接入了服務提供者。同時,實現了服務消費者整合SpringBoot的功能,并且基于SpringBoot接入了服務消費者。
在整合Docker章節,我們實現了基于Docker接入了服務提供者和基于Docker接入了服務消費者。
本章,我們更進一步將手寫的bhrpc框架整合到SpringCloud Alibaba項目。
總之,我們寫的RPC框架正在一步步實現它該有的功能。
最后,我想說的是:學習《RPC手擼專欄》一定要塌下心來,一步一個腳印,動手實踐,認真思考,遇到不懂的問題,可以直接到星球發布主題進行提問。一定要記?。杭埳系脕斫K覺淺,絕知此事要躬行的道理。否則,一味的CP,或者光看不練,不僅失去了學習的意義,到頭來更是一無所獲。