小伙伴们,你们好呀,我是老寇,跟我一起学习dubbo3.3.X
OpenFeign
学习dubbo之前,我们先复习一下spring cloud openfeign,它是基于http/https协议的远程调用组件,需要将借助注册中心(Registry),调用方拉取被调用服务的实例完成远程调用
下面,我们动手体验一下openfeign(springboot 3.2 + springcloud 2023 + jdk21)
admin
1.引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
</dependencies>
2.配置feign
/**
* 需要使用feign默认Request
*/
@Configuration
public class FeignConfig {
@Bean
@ConditionalOnMissingBean
public Contract contract() {
return new Contract.Default();
}
}
3.nacos配置
server:
port: 8085
spring:
application:
name: dubbo-tech-openfeign-admin
cloud:
openfeign:
httpclient:
enabled: false
okhttp:
enabled: true
loadbalancer:
nacos:
enabled: true
nacos:
discovery:
server-addr: nacos.laokou.org
username: nacos
password: nacos
namespace: a61abd4c-ef96-42a5-99a1-616adee531f3
group: DEFAULT_GROUP
4.feign配置
UsersApiFeignClient
@FeignClient(contextId = "users", name = "dubbo-tech-openfeign-user", path = "/v1/users",
fallbackFactory = UsersApiFeignClientFallbackFactory.class)
public interface UsersApiFeignClient {
@RequestLine("GET /test?id={id}")
@Headers("Content-Type: application/json")
void test(@Param("id") String id);
}
UsersApiFeignClientFallback
public class UsersApiFeignClientFallback implements UsersApiFeignClient {
@Override
public void test(String id) {}
}
UsersApiFeignClientFallbackFactory
@Component
public class UsersApiFeignClientFallbackFactory implements FallbackFactory<UsersApiFeignClientFallback> {
@Override
public UsersApiFeignClientFallback create(Throwable cause) {
return new UsersApiFeignClientFallback();
}
}
5.开启注册和feign
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class AdminApp {
public static void main(String[] args) {
SpringApplication.run(AdminApp.class, args);
}
}
6.测试用例
@SpringBootTest
@RequiredArgsConstructor
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
class AdminAppTests {
private final UsersApiFeignClient usersApiFeignClient;
@Test
void userApiFeignTest() {
usersApiFeignClient.test("1");
}
}
user
1.引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
</dependencies>
2.nacos配置
server:
port: 8084
spring:
application:
name: dubbo-tech-openfeign-user
cloud:
loadbalancer:
nacos:
enabled: true
nacos:
discovery:
server-addr: nacos.laokou.org
username: nacos
password: nacos
namespace: a61abd4c-ef96-42a5-99a1-616adee531f3
group: DEFAULT_GROUP
3.api接口编写
@Slf4j
@RestController
@RequestMapping("v1/users")
public class UsersApiController {
@GetMapping("test")
public void test(@RequestParam("id") String id) {
log.info("userApi被调用,id:{}", id);
}
}
4.开启注册
@EnableDiscoveryClient
@SpringBootApplication
public class UserApp {
public static void main(String[] args) {
SpringApplication.run(UserApp.class, args);
}
}
启动user服务,我们可以看到,user服务已经注册上来,点击AdminAppTests测试类
详情代码请查看 dubbo-tech/dubbo-tech-openfeign at main · KouShenhai/dubbo-tech (github.com)
Dubbo
dubbo作为rpc框架,需要引入注册中心(Registry),通过注册中心,消费者(Consumer)可以感知到提供者(Provider),从而确保将请求发送给正确的服务提供者
下面,我们动手体验一下dubbo
api
1.新建接口
public interface UserApi {
String getUserName();
}
provider
1.引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.laokoutech</groupId>
<artifactId>dubbo-tech-sample01-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.3.0-beta.1</version>
</dependency>
<!--注册到nacos引入的依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>3.3.0-beta.1</version>
</dependency>
</dependencies>
2.实现接口
@DubboService(version = "1.0.0")
public class UserApiImpl implements UserApi {
@Override
public String getUserName() {
return "k神";
}
}
3.配置文件
server:
port: 8086
spring:
application:
name: dubbo-tech-sample01-provider
dubbo:
application:
name: ${spring.application.name}
qos-port: 1111
protocol:
id: dubbo
name: dubbo
port: -1
registry:
address: nacos://nacos.laokou.org:8848
username: nacos
group: DEFAULT_GROUP
password: nacos
parameters:
namespace: 8ff3ecc2-9c82-4e7a-a7e1-d840a773e126
register-consumer-url: true
protocol: nacos
4.启动项目
// 开启dubbo
@EnableDubbo
@SpringBootApplication
public class Sample01ProviderApp {
public static void main(String[] args) {
SpringApplication.run(Sample01ProviderApp.class, args);
}
}
consumer
1.引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.laokoutech</groupId>
<artifactId>dubbo-tech-sample01-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.3.0-beta.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>3.3.0-beta.1</version>
</dependency>
</dependencies>
2.测试类
@Slf4j
@SpringBootTest
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
class Sample01ConsumerAppTests {
@DubboReference(version = "1.0.0")
private UserApi userApi;
@Test
public void rpcApiTest() {
String userName = userApi.getUserName();
log.info("dubbo rpc api value:{}", userName);
}
}
3.配置文件
server:
port: 8087
spring:
application:
name: dubbo-tech-sample01-consumer
dubbo:
application:
name: ${spring.application.name}
qos-port: 1112
protocol:
id: dubbo
name: dubbo
port: -1
registry:
address: nacos://nacos.laokou.org:8848
username: nacos
group: DEFAULT_GROUP
password: nacos
parameters:
namespace: 8ff3ecc2-9c82-4e7a-a7e1-d840a773e126
register-consumer-url: true
protocol: nacos
4.启动类
@EnableDubbo
@SpringBootApplication
public class Sample01ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(Sample01ConsumerApp.class, args);
}
}
启动provider,可以看到都注册上nacos,然后我们运行测试类Sample01ConsumerAppTests,RPC调用成功!
详情代码请查看 dubbo-tech/dubbo-tech-sample01 at main · KouShenhai/dubbo-tech (github.com)
RPC与HTTP对比
属性 | HTTP | RPC |
---|---|---|
协议类型 | 应用层协议 | 传输层协议 |
通信方式 | 基于TCP连接 | 基于TCP连接或UDP连接 |
数据传输格式 | 文本格式 | 二进制格式 |
调用方式 | URL调用 | 函数调用 |
参数传递方式 | URL参数,请求体 | 函数参数 |
性能 | 一般 | 高 |
复杂度 | 低 | 高 |
使用场景 | 对外接口、异构环境 | 内部服务调用、高性能场景 |
作者开源了一个企业级微服务架构的脚手架,感兴趣请查看
我是老寇,我们后会有期