> 文章列表 > springcloud各个组件搭配使用演示

springcloud各个组件搭配使用演示

springcloud各个组件搭配使用演示

springcloud各个组件使用demo

Eureka服务注册中心

创建三个eureka服务注册中心,分别为:

eureka-server1

spring:application:name: eureka-server1
server:port: 8001eureka:client:service-url:defaultZone: http://localhost:8002/eureka/,http://localhost:8003/eureka/fetch-registry: trueregister-with-eureka: true

eureka-server2

server:port: 8002
spring:application:name: eureka-server2
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8003/eureka/register-with-eureka: truefetch-registry: true

eureka-server3

server:port: 8003
spring:application:name: eureka-server3
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/fetch-registry: trueregister-with-eureka: true

三个服务注册中心的pom.xml内容一样, 都如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-microservice-parent</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>eureka-server3</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies></project>

其中父pom.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>springboot-microservice-parent</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>eureka-server1</module><module>eureka-server2</module><module>eureka-server3</module><module>goods</module><module>goods2</module><module>ribbon-client</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.6</version><relativePath/></parent><dependencyManagement><dependencies><!--根据springboot的版本指定springCloud的版本--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2020.0.6</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>

eureka-server1、eureka-server2、eureka-server3入口代码相同,都如下:

入口类的类名不同,其他都相同:

EurekaServer1Application.java

EurekaServer2Application.java

EurekaServer3Application.java

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaServer1Application {public static void main(String[] args) {SpringApplication.run(EurekaServer1Application.class, args);}
}

代码结构图

springcloud各个组件搭配使用演示

Eureka客户端

① goods微服务(扮演eureka客户端角色)

application.yaml

server:port: 9001
spring:application:name: goods-server
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/,http://localhost:8003/eureka/

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-microservice-parent</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>goods</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork></configuration></plugin></plugins></build></project>

入口文件

GoodsApplication.java

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class GoodsApplication {public static void main(String[] args) {SpringApplication.run(GoodsApplication.class, args);}
}

测试控制器类: GetGoodsController.java

package com.example.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/goods")
public class GetGoodsController {@Value("${server.port}")private int port;@RequestMapping("/getOne")public String getOneGoods() {return "返回一条数据"+String.valueOf(port);}
}

②goods2微服务(扮演eureka客户端角色), 同goods微服务完全一样

goods2和goods的监听端口不同,其他都一样

goods2的 application.yaml如下:

server:port: 9002
spring:application:name: goods-server
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/,http://localhost:8003/eureka/

启动eureka-server1 eureka-server2 eureka-server3服务端, 再启动goods goods2客户端后, 访问 http://localhost:8001, http://localhost:80012, http://localhost:8003 如下:

springcloud各个组件搭配使用演示

可以看到, 各个微服务都已经注册到注册中心了; 其中的微服务RIBBON-SERVER是后面要演示的负载均衡调用组件

负载均衡调用组件 Ribbon

pom.xml

一定要避开一个坑: Ribbon组件和Eureka-client不要同时引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-microservice-parent</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ribbon-client</artifactId><dependencies><!-- eureka-client 已经集成了loadbalanced了,不需要在引入ribbon了,否则引起会冲突,但是启动的时候也不报这个冲突的错误,这里一定要避开这个坑!!!,否则后面调试让你头大,报错一直找不到微服务GOODS-SERVER实例 --><!--<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.4.RELEASE</version></dependency>--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><fork>true</fork></configuration></plugin></plugins></build></project>

application.yaml

server:port: 10001
spring:application:name: ribbon-server
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/,http://localhost:8003/eureka/

微服务入口文件RibbonClientApplication.java

入口类上不要再标注@RibbonClient注解了

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
// @RibbonClient(name = "GOODS-SERVER") //eureka-client组件已经引入了loadbalance了, 不需要在导入ribbon组件了
public class RibbonClientApplication {public static void main(String[] args) {SpringApplication.run(RibbonClientApplication.class, args);}
}

配置文件MyRestTemplate.java

package com.example.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class MyRestTemplate {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

控制器BalanceRequest.java

package com.example.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;/* 测试 ribbon负载均衡远程调用*/
@RestController
@RequestMapping("/ribbon")
public class BalanceRequest {@Autowiredprivate DiscoveryClient discoveryClient;@Autowiredprivate LoadBalancerClient loadBalancerClient;@Autowiredprivate RestTemplate restTemplate;//根据类型,会导入我们自己定义的MyRestTemplate类@RequestMapping("getGoods")public String getGoods() {//方式一:// RestTemplate restTemplate = new RestTemplate();// String forObject = restTemplate.getForObject("http://localhost:9001/goods/getOne", String.class);// System.out.println(forObject);// return forObject;//方式二//getServices()获取所有注册在注册中心的服务// List<String> services = discoveryClient.getServices();// for (String service : services) {//     System.out.println(service);// }//获取某个服务id下的所有信息// List<ServiceInstance> instances = discoveryClient.getInstances("GOODS-SERVER");// for (ServiceInstance instance : instances) {//     System.out.println(instance.getHost());//     System.out.println(instance.getPort());//     // System.out.println(instance.getMetadata());//     System.out.println(instance.isSecure());//     System.out.println(instance.getUri().toString());//     System.out.println(instance.getServiceId());//     System.out.println(instance.getScheme());// }// RestTemplate restTemplate = new RestTemplate();// // String forObject = restTemplate.getForObject(instances.get(0).getUri() + "/goods/getOne", String.class);// String forObject = restTemplate.getForObject(instances.get(1).getUri() + "/goods/getOne", String.class);// return forObject;//方式三: 坑!! 一直报错: loadBalancerClient.choose("goods-server")返回null, 原因就是同时导入了ribbon依赖,又有eureka-client依赖; eureka-client包中已经有了ribbon核心组件中的loadbalanced了,不需要再导入ribbon了// System.out.println("");// System.out.println(loadBalancerClient);// System.out.println(loadBalancerClient.choose("goods-server"));// System.out.println(loadBalancerClient.choose("GOODS-SERVER"));// System.out.println("");//// ServiceInstance choose = loadBalancerClient.choose("GOODS-SERVER");// ServiceInstance choose2 = loadBalancerClient.choose("goods-server");//// System.out.println("++++++++++++++++++++++");// System.out.println(choose);// System.out.println(choose2);// System.out.println(choose.getUri().toString());// System.out.println(choose.getHost());// System.out.println(choose.getPort());// System.out.println("++++++++++++++++++++++");// ServiceInstance choose = loadBalancerClient.choose("GOODS-SERVER");// RestTemplate restTemplate = new RestTemplate();// String forObject = restTemplate.getForObject(choose.getUri() + "/goods/getOne", String.class);// System.out.println(forObject);// return forObject;//方式四://如果不清楚eureka-client已经内置导入了loadbalance了,而再次导入Ribbon组件的话,将一直报错:找不到服务...: No instances available for GOODS-SERVER,坑!!!String forObject = restTemplate.getForObject("http://goods-server/goods/getOne", String.class);System.out.println(forObject);return forObject;}
}

代码接口图如下:

springcloud各个组件搭配使用演示

postman测试结果如下:

默认轮询的方式展示返回结果

第一次请求返回9001 再次请求返回9002
springcloud各个组件搭配使用演示 springcloud各个组件搭配使用演示

OpenFeign远程调用组件

openFeign的详细使用, 参考: https://blog.csdn.net/zyb18507175502/article/details/126682187
这里使用 OpenFeign远程调用goods微服务springcloud各个组件搭配使用演示

pom.xml内容如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springboot-microservice-parent</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>feign-client</artifactId><dependencies><!--feign代替RestTemplate进行远程调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

application.yaml内容如下

server:port: 11001
spring:application:name: feignclient-server
eureka:client:service-url:defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/,http://localhost:8003/eureka/

FeignClientApplication.java

package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableDiscoveryClient //当服务注册中心不限于eureka, 如consul,nacos等, 任何的服务注册中心都可以使用该注解标注客户端,范围更广
// @EnableEurekaClient//只能是Eureka作为服务注册中心时,使用该注解标注为客户端,范围较局限
@EnableFeignClients // 表明需要使用feign进行远程调用
public class FeignClientApplication {public static void main(String[] args) {SpringApplication.run(FeignClientApplication.class, args);}
}

MyFeignClient.java

package com.example.client;import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;@FeignClient("GOODS-SERVER")
public interface MyFeignClient {//直接将goods或者goods2项目中的 getOneGoods()方法粘贴过来,去掉方法体就行//将goods微服务的类上的路径和方法上的路径合并后的最终路径写在这里@RequestMapping("/goods/getOne")String getOneGoods();
}

FeignClientGetGoodsController.java

package com.example.controller;import com.example.client.MyFeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/* 使用feignClient 代替RestTemplate进行远程调用*/
@RestController
@RequestMapping("/feignClient")
public class FeignClientGetGoodsController {// @Autowired@Resourceprivate MyFeignClient myFeignClient;@RequestMapping("/getGoods")public String getGoods() {System.out.println("请求到来!");String oneGoods = myFeignClient.getOneGoods();return oneGoods;}
}

代码结构如下图:

springcloud各个组件搭配使用演示

postman调用结果如下:

http://localhost:11001/feignClient/getGoods

springcloud各个组件搭配使用演示 springcloud各个组件搭配使用演示
第一次调用返回9002 第二次调用9001