五分钟带你玩转springcloudNetflix(四)服务间调用

举报
小鲍侃java 发表于 2021/09/10 23:07:48 2021/09/10
【摘要】 上文我们把我们项目注册到服务器上了,但是我们会使用A服务调用B服务,那么就会使用服务的调用,这里有两种方式ribbon和feign,我们分别介绍。 ribbon ribbon说白了就是使用restTemplate。下面上代码 首先pom文件 <?xml version="1.0" encoding="UTF-8"?>...

上文我们把我们项目注册到服务器上了,但是我们会使用A服务调用B服务,那么就会使用服务的调用,这里有两种方式ribbon和feign,我们分别介绍。

ribbon

ribbon说白了就是使用restTemplate。下面上代码

首先pom文件


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.5.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.baocl</groupId>
  12. <artifactId>eureka-consumer</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>eureka-consumer</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
  19. </properties>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-web</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.cloud</groupId>
  27. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework.boot</groupId>
  35. <artifactId>spring-boot-starter-test</artifactId>
  36. <scope>test</scope>
  37. <exclusions>
  38. <exclusion>
  39. <groupId>org.junit.vintage</groupId>
  40. <artifactId>junit-vintage-engine</artifactId>
  41. </exclusion>
  42. </exclusions>
  43. </dependency>
  44. </dependencies>
  45. <dependencyManagement>
  46. <dependencies>
  47. <dependency>
  48. <groupId>org.springframework.cloud</groupId>
  49. <artifactId>spring-cloud-dependencies</artifactId>
  50. <version>${spring-cloud.version}</version>
  51. <type>pom</type>
  52. <scope>import</scope>
  53. </dependency>
  54. </dependencies>
  55. </dependencyManagement>
  56. <build>
  57. <plugins>
  58. <plugin>
  59. <groupId>org.springframework.boot</groupId>
  60. <artifactId>spring-boot-maven-plugin</artifactId>
  61. </plugin>
  62. </plugins>
  63. </build>
  64. </project>

然后EurekaConsumerApplication类

需要在新建RestTemplate的bean


  
  1. package com.cloud;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.web.client.RestTemplate;
  8. @SpringBootApplication
  9. @EnableDiscoveryClient
  10. public class EurekaConsumerApplication {
  11. @Bean
  12. @LoadBalanced // ribbon注解
  13. public RestTemplate restTemplate() {
  14. return new RestTemplate();
  15. }
  16. public static void main(String[] args) {
  17. SpringApplication.run(EurekaConsumerApplication.class, args);
  18. }
  19. }

DcController

新建接口 调用上文服务


  
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.cloud.client.discovery.DiscoveryClient;
  3. import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
  4. import org.springframework.http.ResponseEntity;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import org.springframework.web.client.RestTemplate;
  9. @RestController
  10. @RequestMapping("/eureka1")
  11. public class DcController {
  12. @Autowired
  13. LoadBalancerClient loadBalancerClient;
  14. @Autowired
  15. RestTemplate restTemplate;
  16. @Autowired
  17. DiscoveryClient discoveryClient;
  18. @GetMapping("/consumer")
  19. public ResponseEntity<String> dc() {
  20. //String url = "http://eureka-client/aaa/dc?dk=3001";
  21. String url = "http://EUREKA-CLIENT/aaa/dc?dk=3001";
  22. System.out.println(url);
  23. // ServiceInstance serviceInstance =
  24. // loadBalancerClient.choose("eureka-client");// 获取服务提供者信息
  25. // // String url = "http://localhost:" + serviceInstance.getPort() + "/aaa/dc";
  26. // System.out.println(serviceInstance.getPort() );
  27. // System.out.println(url);
  28. // ResponseEntity r = restTemplate.getForEntity("http://eureka-client/aaa/dc",
  29. // String.class);
  30. // System.out.println("r.getHeaders().getHost():"+r.getHeaders().getHost());
  31. // System.out.println("r.getHeaders().getLocation():"+r.getHeaders().getLocation());
  32. // System.out.println("r.getHeaders().getOrigin():"+r.getHeaders().getOrigin());
  33. return restTemplate.getForEntity(url, String.class); // ribbon应用
  34. }
  35. }

有一个坑  在调用时候需要

String url = "http://eureka-client/aaa/dc?dk=3001";
 

而不是

String url = "http://localhost:2002/aaa/dc?dk=3001";
 

否则会报错。

java.lang.IllegalStateException: No instances available for localhost
 

最后是配置文件application.yml

这里我们使用.yml文件 都是基础配置


  
  1. eureka:
  2. client:
  3. registery-fetch-interval-seconds: 5000
  4. serviceUrl:
  5. defaultZone: http://localhost:1001/eureka/
  6. eureka-client:
  7. ribbon:
  8. NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
  9. server:
  10. port: 3001
  11. spring:
  12. application:
  13. name: eureka-consumer

输入http://localhost:3001/eureka1/consumer就可以调用到上文的client服务了,同时还会使用顺序调用负载均衡策略。

 

feign

EurekaConsumerFeignApplication

首先在EurekaConsumerFeignApplication使用@EnableFeignClients中开启feign


  
  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  4. import org.springframework.cloud.openfeign.EnableFeignClients;
  5. @EnableFeignClients
  6. @EnableDiscoveryClient
  7. @SpringBootApplication
  8. public class EurekaConsumerFeignApplication {
  9. public static void main(String[] args) {
  10. SpringApplication.run(EurekaConsumerFeignApplication.class, args);
  11. }
  12. }

新建一个接口DcClient

配置调用其他服务的名称和接口名称


  
  1. import org.springframework.cloud.openfeign.FeignClient;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. @FeignClient(name = "eureka-client")
  4. public interface DcClient {
  5. @GetMapping("/aaa/dc?dk=3002")
  6. String consumer();
  7. @GetMapping("/aaa/dc?dk=3002")
  8. String consumer2();
  9. }

DcController

业务接口的书写 同时注入dcClient调用其他服务


  
  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. import com.cloud.DcClient;
  6. @RestController
  7. @RequestMapping("/eureka2")
  8. public class DcController {
  9. @Autowired
  10. DcClient dcClient;
  11. @GetMapping("/consumer")
  12. public String dc() {
  13. return dcClient.consumer();
  14. }
  15. }

application.properties

基础配置


  
  1. spring.application.name=eureka-consumer-feign
  2. server.port=3002
  3. eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/

pom文件

版本问题一定要控制!!!!


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.5.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.baocl</groupId>
  12. <artifactId>eureka-consumer-feign</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>eureka-consumer-feign</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
  19. </properties>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-web</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.cloud</groupId>
  27. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-starter-feign</artifactId>
  32. <version>1.4.7.RELEASE</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-test</artifactId>
  37. <scope>test</scope>
  38. <exclusions>
  39. <exclusion>
  40. <groupId>org.junit.vintage</groupId>
  41. <artifactId>junit-vintage-engine</artifactId>
  42. </exclusion>
  43. </exclusions>
  44. </dependency>
  45. </dependencies>
  46. <dependencyManagement>
  47. <dependencies>
  48. <dependency>
  49. <groupId>org.springframework.cloud</groupId>
  50. <artifactId>spring-cloud-dependencies</artifactId>
  51. <version>${spring-cloud.version}</version>
  52. <type>pom</type>
  53. <scope>import</scope>
  54. </dependency>
  55. </dependencies>
  56. </dependencyManagement>
  57. <build>
  58. <plugins>
  59. <plugin>
  60. <groupId>org.springframework.boot</groupId>
  61. <artifactId>spring-boot-maven-plugin</artifactId>
  62. </plugin>
  63. </plugins>
  64. </build>
  65. </project>

这里有一个坑 就是版本问题,有时会报错

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: file [F:\workspace\springcloud\tse9\eureka-consumer-feign\target\classes\com\cloud\DcClient.class]; nested exception is org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.cloud.netflix.feign.FeignClient] must be declared as an @AliasFor 'serviceId', not 'name'.

 

解决办法http://www.pianshen.com/article/2239869942/

然后调用http://localhost:3002/eureka2/consumer 可以发现接口掉通了 帮帮哒

ribbon和Eureka整合原理

基本流程就是 客户端从eureka中获取到缓存的服务列表,获取到目的服务的信息,然后通过自身的负载均衡策略,去调用对应的服务

负载均衡策略

BestAvailableRule 选择一个最小的并发请求的server. AvailabilityFilteringRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值). WeightedResponseTimeRule 根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低. RetryRule 对选定的负载均衡策略机上重试机制. RoundRobinRule roundRobin方式轮询选择server. RandomRule 随机选择一个server. ZoneAvoidanceRule 复合判断server所在区域的性能和server的可用性选择server.
 

文章来源: baocl.blog.csdn.net,作者:小黄鸡1992,版权归原作者所有,如需转载,请联系作者。

原文链接:baocl.blog.csdn.net/article/details/104738600

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。