有一批restful應用,性能問題需要引入rpc框架,不太希望影響原來的業務服務,包括springcloud全家桶;考慮到改造成本問題,rpc框架選型dubbo,保留原來的restful服務,兼容歷史邏輯,開搞。
server端應用創建
為了不暴露敏感代碼,直接在spring Initializr上創建一個簡單的springboot項目
創建項目
可以看到,這裡選擇的三個依賴,分別是:
spring web:用於提供restful訪問能力lombok:習慣用它來節約代碼spring configuration processor:提供針對yml等配置文件的支持下載之後解壓,使用idea打開即可,這時項目的pom依賴如下:
<code>
<project> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0/<modelversion>
<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>2.2.5.RELEASE/<version>
<relativepath>
/<parent>
\t<groupid>com.rpc.server/<groupid>
<artifactid>rpcserver/<artifactid>
<version>0.0.1-SNAPSHOT/<version>
<name>rpcserver/<name>
<description>Demo project for Spring Boot/<description>
\t<properties>
<java.version>1.8/<java.version>
/<properties>
\t<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-configuration-processor/<artifactid>
<optional>true/<optional>
/<dependency>
<dependency>
<groupid>org.projectlombok/<groupid>
<artifactid>lombok/<artifactid>
<optional>true/<optional>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-test/<artifactid>
<scope>test/<scope>
<exclusions>
<exclusion>
<groupid>org.junit.vintage/<groupid>
<artifactid>junit-vintage-engine/<artifactid>
/<exclusion>
/<exclusions>
/<dependency>
/<dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-maven-plugin/<artifactid>
/<plugin>
/<plugins>
/<build>
/<project>/<code>
直接一個Controller
<code>import com.grpc.dubbo.server.grpcserver.service.HomeServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController("grpcServerController")
@RequestMapping("/server")
public class GrpcServerController {
@RequestMapping(value = "/home",method = RequestMethod.GET)
public String serverHome(){
return "Server Home";
}
}/<code>
加入部分配置,默認的application.properties 改名成 application.yml,寫起來更簡單
<code>import com.grpc.dubbo.server.grpcserver.service.HomeServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController("grpcServerController")
@RequestMapping("/server")
public class GrpcServerController {
@Autowired
private HomeServerService homeServerService;
@RequestMapping(value = "/home",method = RequestMethod.GET)
public String serverHome(){
return homeServerService.homeServer("ALAN");
}
}/<code>
OK,最簡單的server端就完成了,項目根目錄下mvn spring-boot:run執行,然後http訪問:
http://localhost:8090/server/home
拆分出rpcserver-api module
最簡單的springboot項目完成,對外提供http接口。下面開始引入dubbo框架。
直接使用dubbo-spring-boot-starter 或者 直接使用spring cloud alibaba,都會引入過多的依賴,可能對原有系統的依賴產生衝突,所以這裡使用滿足最基本需要的dubbo依賴引入。
首先,需要拆分項目,因為dubbo對外暴露出的service必須是一個接口,且調用方需要引入包含對應接口定義的api包依賴,所以拆出rpcserver-api,只定義接口和對應的參數,且不需要額外依賴。
使用idea創建一個名為 rpcserver-api的maven類型module。
api pom.xml如下:
<code>
<project> 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">
<parent>
<artifactid>grpcserver/<artifactid>
<groupid>com.grpc.dubbo.server/<groupid>
<version>0.0.1-SNAPSHOT/<version>
/<parent>
<modelversion>4.0.0/<modelversion>
<artifactid>grpcserver-api/<artifactid>
/<project>/<code>
對應的service接口定義:
<code>package com.grpc.dubbo.server.grpcserver.service;
public interface HomeServerService {
String homeServer(String name);
}
/<code>
拆分出rpcserver-service
然後繼續拆分,使用idea創建另一個rpcserver-service的module,並將所有剩餘的代碼(controller)、配置(application.yml)都移入此module。
先修改項目根pom.xml
1、在<dependencies>外包裝一層<dependencymanagement>
2、由於spring-boot-maven-plugin只需要在可執行的module中配置,所以將其轉移到rpcserver-service pom.xml中
<code> <build>
<plugins>
<plugin>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-maven-plugin/<artifactid>
/<plugin>
/<plugins>
/<build>/<code>
在rpcserver-service pom.xml中引入父pom中所有4個依賴,保證沒有編譯錯誤。
豐富rpcserver-service中功能
由於目前依然只有一個controller,而我們還有一個接口沒有實現,在這裡做個實現
改寫controller:
<code>@RestController("grpcServerController")
@RequestMapping("/server")
public class GrpcServerController {
@Autowired
private HomeServerService homeServerService;
@RequestMapping(value = "/home",method = RequestMethod.GET)
public String serverHome(){
return homeServerService.homeServer("ALAN");
}
}/<code>
實現HomeServerService
<code>package com.grpc.dubbo.server.gprcserver.service.impl;
import com.grpc.dubbo.server.grpcserver.service.HomeServerService;
import org.springframework.stereotype.Component;
@Component
public class HomeServerServiceImpl implements HomeServerService {
@Override
public String homeServer(String name) {
return "Home Server!!" + name;
}
}
/<code>
修改完成之後,整個項目目錄結構如下:
這麼改造後,直接在根目錄中使用命令 mvn --projects rpcserver-service spring-boot:run可以繼續正常運行,與原來一樣。
引入dubbo
這裡引入dubbo只是在原來springcloud全家桶上增加了底層rpc通信框架,並未影響原有http服務,原來的feign、robbin等依然可以繼續使用。
先引入依賴,在跟pom.xml中增加以下依賴:
<code>
<dependency>
<groupid>org.apache.dubbo/<groupid>
<artifactid>dubbo/<artifactid>
<version>2.7.5/<version>
/<dependency>
<dependency>
<groupid>org.apache.zookeeper/<groupid>
<artifactid>zookeeper/<artifactid>
<version>3.4.6/<version>
<exclusions>
<exclusion>
<groupid>org.slf4j/<groupid>
<artifactid>slf4j-log4j12/<artifactid>
/<exclusion>
<exclusion>
<groupid>log4j/<groupid>
<artifactid>log4j/<artifactid>
/<exclusion>
<exclusion>
<artifactid>netty/<artifactid>
<groupid>io.netty/<groupid>
/<exclusion>
/<exclusions>
/<dependency>
<dependency>
<groupid>org.apache.curator/<groupid>
<artifactid>curator-framework/<artifactid>
<version>4.3.0/<version>
<exclusions>
<exclusion>
<artifactid>zookeeper/<artifactid>
<groupid>org.apache.zookeeper/<groupid>
/<exclusion>
/<exclusions>
/<dependency>
<dependency>
<groupid>org.apache.curator/<groupid>
<artifactid>curator-recipes/<artifactid>
<version>4.3.0/<version>
/<dependency>/<code>
需要注意的是,需要排除curator-framework中默認間接依賴的zookeeper 3.5.X版本,而是用直接引入的3.4.X版本,不然會有衝突。
同時在service pom.xml引入對應的dubbo依賴。
dubbo配置
引入dubbo依賴後,有幾種方式可以對外暴露dubbo服務,不過還是傾向於使用xml配置的方式,這樣對原有代碼沒有任何改造,詳見文檔:http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html
下面是在resources下設置的provider.xml
<code><beans> xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<application>
<parameter>
<parameter>
<parameter>
/<application>
<registry>
<protocol>
<service> version="1.0.1" timeout="300" loadbalance="random">
<method>
/<service>
/<beans>/<code>
說明下
group設置不能在設置在dubbo:registry下,否則會出現客戶端無法找到對應服務的異常,除非客戶端也在dubbo:registry下設置了同樣的groupgroup分組可以放在service層面上,關於group的說明詳見:http://dubbo.apache.org/zh-cn/docs/user/demos/service-group.htmldubbo:service中默認版本是1.0.0,如果設置了其他的version,在調用方也需要指定相同的version,否則會出現無法找到對應服務的問題。在GrpcserverApplication項目啟動類中,增加對provider.xml的加載,如下
<code>@SpringBootApplication
@ImportResource("classpath:provider.xml")
public class GrpcserverApplication {
\tpublic static void main(String[] args) {
\t\tSpringApplication.run(GrpcserverApplication.class, args);
\t}
}
/<code>
重新啟動服務
重啟服務,在dubbo-admin後臺可以看到以下內容