服务间调用操作手册

Dubbo 解决方案

参考文档

common
项目初始化

新建空的 Maven 项目

公共接口声明
public interface SayService {

   /**
    * 根据名字say hello
    * @param name 名字
    * @return name + ,hello!
    */
   String sayHelloByName(String name);
}
依赖安装
mvn install
provider
项目初始化

初始化为 Spring Boot 项目(版本:2.7.14)

Maven 依赖
  • Spring Boot 基础依赖

  • dubbo 基础依赖

  • dubbo 注册中心依赖:相当于 nacos-client

<dependencies>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>

   <dependency>
       <groupId>org.apache.dubbo</groupId>
       <artifactId>dubbo-spring-boot-starter</artifactId>
       <version>3.0.9</version>
   </dependency>

   <dependency>
       <groupId>org.apache.dubbo</groupId>
       <artifactId>dubbo-registry-nacos</artifactId>
       <version>3.0.9</version>
   </dependency>

   <dependency>
       <groupId>org.example</groupId>
       <artifactId>common</artifactId>
       <version>1.0-SNAPSHOT</version>
   </dependency>

</dependencies>
application.yml
server:
port: 14511
spring:
application:
  name: provider-service
main:
  allow-bean-definition-overriding: true
dubbo:
application:
  name: provider-service
registry:
  address: nacos://127.0.0.1:8848
  username: nacos
  password: nacos
scan:
  base-packages: com.example.provider.service.impl
protocol:
  name: dubbo
  port: 15511
公共接口实现
@DubboService
public class SayServiceImpl implements SayService {

   @Override
   public String sayHelloByName(String name) {
       return name + ",hello!";
  }
}
启动类
@EnableDubbo
@SpringBootApplication
public class ProviderApplication {

   public static void main(String[] args) {
       SpringApplication.run(ProviderApplication.class, args);
  }

}
consumer
项目初始化

初始化为 Spring Boot 项目(版本:2.7.14)

Maven 依赖
<dependencies>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter</artifactId>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>

   <dependency>
       <groupId>org.apache.dubbo</groupId>
       <artifactId>dubbo-spring-boot-starter</artifactId>
       <version>3.0.9</version>
   </dependency>

   <dependency>
       <groupId>org.apache.dubbo</groupId>
       <artifactId>dubbo-registry-nacos</artifactId>
       <version>3.0.9</version>
   </dependency>

   <dependency>
       <groupId>org.example</groupId>
       <artifactId>common</artifactId>
       <version>1.0-SNAPSHOT</version>
   </dependency>

</dependencies>
application.yml
server:
port: 14510
spring:
application:
  name: consumer-serivce
main:
  allow-bean-definition-overriding: true
dubbo:
application:
  name: consumer-serivce
registry:
  address: nacos://127.0.0.1:8848
  username: nacos
  password: nacos
Controller
@RestController
@RequestMapping("/demo/say")
public class SayController {

   @DubboReference
   private SayService sayService;

   @GetMapping("/sayHello")
   public ResponseEntity<String> sayHello(@RequestParam("name") String name) {
       return ResponseEntity.ok(sayService.sayHelloByName(name));
  }
}
启动类
@EnableDubbo
@SpringBootApplication
public class ConsumerApplication {

   public static void main(String[] args) {
       SpringApplication.run(ConsumerApplication.class, args);
  }

}
测试流程
  1. Provider 启动

  2. Consumer 启动

  3. 通过 Consumer 的 Controller 访问 Provider 的 Service

    curl "http://127.0.0.1:14510/demo/say/sayHello?name=test"

 

RestTemplate 按 IP 调用

本质上就是在项目内部发送一个 HTML 请求,由于 HTML 的跨平台特性,后端发送的请求等价于前端发过来的请求

RestTemplate restTemplate = new RestTemplate();
String name = "Ba11ooner";
restTemplate.getForEntity("http://172.0.0.1:8080/demo/say?name="+ name,null);

RestTemplate + Nacos 实现按名调用

关键点在于配置好 Feign 和 LoadBalancer

provider
项目初始化

初始化为 Spring Boot 项目(版本:2.7.14)

本质上是一个通过 Controller 暴露内部服务的普通 Web 后端

Maven 依赖
  • spring-boot-starter-web:这是Spring Boot框架的核心依赖,用于创建Web应用。

  • spring-cloud-alibaba-dependencies:这是Spring Cloud Alibaba的依赖管理器,用于集成Spring Cloud Alibaba的各个组件。

  • spring-cloud-starter-alibaba-nacos-discovery:这是用于集成Nacos作为服务注册与发现的组件。

    <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-alibaba-dependencies</artifactId>
           <version>2021.0.5.0</version>
           <type>pom</type>
       </dependency>

       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
           <version>2021.0.5.0</version>
       </dependency>
</dependencies>
application.yaml
server:
port: 8080
spring:
application:
  name: provider-service
cloud:
  nacos:
    discovery:
      server-addr: 127.0.0.1:8848
Controller
@RestController
@RequestMapping("/demo")
public class SayController {
 @Resource
SayService service;

 @GetMapping("/say")
 public String getNameByGet(@RequestParam String name) {
     return service.sayHelloByName(name);
}
 
}
启动类
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {

   public static void main(String[] args) {
       SpringApplication.run(ProviderApplication.class, args);
  }

}
consumer
项目初始化

初始化为 Spring Boot 项目(版本:2.7.14)

本质上是通过 FeignClient + Naocs 实现内部按名调用服务

Maven 依赖
  • spring-boot-starter-web:启动Spring Boot的Web应用程序所需的依赖包。

  • spring-cloud-starter-loadbalancer:提供负载均衡功能的依赖包。它包含了相应的负载均衡算法和服务发现的实现。

  • spring-cloud-starter-openfeign:使用OpenFeign进行服务间的通信所需的依赖包。OpenFeign是一个声明式的Web服务客户端,简化了服务间的调用过程。

  • spring-cloud-dependenciesspring-cloud-alibaba-dependencies 是依赖管理POM文件,用于确保Spring Cloud 和 Spring Cloud Alibaba 组件版本之间的兼容性。

<dependencies>
 
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
 
 <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-loadbalancer</artifactId>
   </dependency>

   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-openfeign</artifactId>
   </dependency>

</dependencies>


<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-dependencies</artifactId>
           <version>2021.0.5</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-alibaba-dependencies</artifactId>
           <version>2021.0.5.0</version>
           <type>pom</type>
           <scope>import</scope>
       </dependency>
   </dependencies>
</dependencyManagement>
application.yaml
server:
port: 8081
spring:
application:
  name: consumer-serivce
cloud:
  nacos:
    discovery:
      server-addr: 127.0.0.1:8848
  loadbalancer:
    nacos:
      enabled: true
配置类
public class LoadBalancerConfig {
   //将官方提供的 RandomLoadBalancer 注册为Bean
   @Bean
   public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){
       String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
       return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
  }
}
//BeanConfig
@Configuration
@LoadBalancerClient(
       //指定为 provider-service 服务,只要是调用此服务都会使用我们指定的策略
value = "provider-service",      
       configuration = LoadBalancerConfig.class)   //指定我们刚刚定义好的配置类
public class BeanConfig {
   @Bean
   @LoadBalanced
   RestTemplate template(){
       return new RestTemplate();
  }
}
FeignClient
@FeignClient("provider-service")
public interface DemoClient {

   @GetMapping("/demo/say")
   void getNameByGet(@RequestParam String name);

}
Controller
//实现服务调用,本质上并不承担服务执行的职责
@RestController
@RequestMapping("/demo/say")
public class InvokeController {
 
   @Autowired
   private LoadBalancerClient loadBalancerClient;

   // 创建 RestTemplate 实例
   @Autowired
   private RestTemplate restTemplate;

   @Resource
   DemoClient demoClient;
 
   void requestByGet() {
       ServiceInstance serviceInstance = loadBalancerClient.choose("provider-service");
       String name = "Ba11ooner";
       demoClient.getNameByGet(name);
  }
 
 
   @GetMapping("/request")
   public ResponseEntity<String> sendRequest() {
       requestByGet();
       return ResponseEntity.ok("200");
  }
}
启动类
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {

   public static void main(String[] args) {
       SpringApplication.run(ProviderApplication.class, args);
  }

}
 


 
posted @ 2023-09-05 15:37  Ba11ooner  阅读(56)  评论(0编辑  收藏  举报