Spring Cloud 提供 RestTemplate 和 FeignClient 方式完成服务间调用,好的微服务架构-服务调用 应该遵循 对外REST,对内RPC这个原则,为什么选择用RPC,在下面列出了RPC和REST不同之处
RPC
REST
耦合性
强耦合
松散耦合
信息协议
二进制
文本XML,JSON
通讯协议
TCP(传输层)
HTTP/HTTP2(应用层)
性能
高
低于RPC
解决方案
Dubbo,Tars
Spring MVC
开发者友好
二进制不可读
文本信息可读
下面开始我们应用开发Spring Cloud + Nacos + Apache Dubbo,项目结构如下
项目
介绍
dubbo-consumer-echo
echo消费者
dubbo-provider-echo
echo服务
dubbo-api-echo
接口定义
dubbo-api-echo
pom.xml
<dependencies>
<!--spring boot dubbo-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>2.7.3</version>
</dependency>
<!-- dubbo-serialization-kryo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-kryo</artifactId>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
<version>2.7.2</version>
</dependency>
<!-- Alibaba Spring Context extension -->
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-kryo</artifactId>
<version>2.7.2</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
项目结构
echoService
package com.spring.cloud.dubbo.api;
public interface EchoService {
String echo(String text);
}
dubbo-provider
pom.xml
<dependencies>
<!-- Spring Cloud -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.bob4F.spring.cloud</groupId>
<artifactId>dubbo-api-echo</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
application.yml
spring:
main:
allow-bean-definition-overriding: true
application:
name: echo-provider
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 10101
dubbo:
application:
name: echo-provider
registry:
# 注册
address: nacos://127.0.0.1:8848
# 配置namespace
parameters[namespace]: 8527532d-20d6-48e3-9b53-508003892f44
scan:
basePackages: com.spring.cloud.dubbo
启动类
@EnableDiscoveryClient
@EnableDubbo
@SpringBootApplication
@ComponentScan("com.spring.cloud.dubbo")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(10880);
protocolConfig.setName("dubbo");
return protocolConfig;
}
}
服务实现
import com.spring.cloud.dubbo.api.EchoService;
import org.apache.dubbo.config.annotation.Service;
import java.util.concurrent.TimeUnit;
@Service(timeout = 5000,version = "1.0.0")
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String text) {
long start = System.currentTimeMillis();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
long end = System.currentTimeMillis();
return "
" + start + " Provider received." +
"
Provider processed after sleep 1 second! Echo String: "" + text + """ +
"
" + end + " Provider Return";
}
}
dubbo-consumer-echo
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.bob4F.spring.cloud</groupId>
<artifactId>dubbo-api-echo</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
application.yml
server:
port: 8088
spring:
main:
allow-bean-definition-overriding: true
application:
name: echo-consumer
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
dubbo:
application:
name: dubbo-consumer-echo
registry:
address: nacos://127.0.0.1:8848
parameters[namespace]: 8527532d-20d6-48e3-9b53-508003892f44
scan:
basePackages: com.spring.cloud.dubbo
启动类
@EnableDiscoveryClient
@EnableDubbo
@SpringBootApplication
@ComponentScan("com.spring.cloud.dubbo")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(20880);
protocolConfig.setName("dubbo");
return protocolConfig;
}
}
消费接口
@RestController
public class EchoController {
@Reference(version = "1.0.0")
EchoService echoService;
@GetMapping("/echo/")
public Object echo(){
try {
return echoService.echo("hi,Echo");
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
在 test 命名空间中查看我们注册的服务
到这里就把实现了 Nacos + Apache Dubbo 实现内部服务调用啦
参考资料
千锋教育:Spring Cloud Alibaba+ Dubbo 实现了通过Feign兼容HTTP以及RPC内部调用
giuthub:springcloud_dubbo 对上面的项目进行了dubbo版本的更新,从2.6.x更新到了2.7.x,区别是2.7已经属于Apache的开源项目