dubbo 3.3.X 入门

417 阅读3分钟

小伙伴们,你们好呀,我是老寇,跟我一起学习dubbo3.3.X

image.png

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);
    }
}

image.png

启动user服务,我们可以看到,user服务已经注册上来,点击AdminAppTests测试类

image.png

详情代码请查看 dubbo-tech/dubbo-tech-openfeign at main · KouShenhai/dubbo-tech (github.com)

Dubbo

image.png

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);
    }
}

image.png 启动provider,可以看到都注册上nacos,然后我们运行测试类Sample01ConsumerAppTests,RPC调用成功! image.png

详情代码请查看 dubbo-tech/dubbo-tech-sample01 at main · KouShenhai/dubbo-tech (github.com)

RPC与HTTP对比
属性HTTPRPC
协议类型应用层协议传输层协议
通信方式基于TCP连接基于TCP连接或UDP连接
数据传输格式文本格式二进制格式
调用方式URL调用函数调用
参数传递方式URL参数,请求体函数参数
性能一般
复杂度
使用场景对外接口、异构环境内部服务调用、高性能场景

作者开源了一个企业级微服务架构的脚手架,感兴趣请查看

KouShenhai/KCloud-Platform-Alibaba: KCloud-Platform-Alibaba(老寇云平台)是一个企业级微服务架构的云服务平台。基于Spring Boot 3.2.0、Spring Cloud 2023.0.0、Spring Cloud Alibaba 2022.0.0.0 最新版本开发的多租户SaaS系统,家人们,点个star!拜托啦~ (github.com)

我是老寇,我们后会有期