搭建Spring Boot+Spring Cloud微服务

末蓝、 2023-02-22 12:24 95阅读 0赞

一、先创建两个Spring Boot项目

利用SpringCloud来将两个服务关联起来,使其可以互相调用

名称分别为:spring-cloud-a、spring-cloud-b

端口分别为:8001和8002
二、搭建eureka注册中心

SpringCloud采用的是Eureka来做服务的注册中心,类似于dubbo采用的是zookeeper作为注册中心一样

(1)创建一个新的springboot项目,名称为spring-cloud-eureka,端口为8003

(2)pom.xml里添加

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-eureka-server</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>ch.qos.logback</groupId>
  8. <artifactId>logback-classic</artifactId>
  9. <version>1.2.1</version>
  10. </dependency>
  11. </dependencies>
  12. <dependencyManagement>
  13. <dependencies>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-dependencies</artifactId>
  17. <version>Brixton.RELEASE</version>
  18. <type>pom</type>
  19. <scope>import</scope>
  20. </dependency>
  21. </dependencies>
  22. </dependencyManagement>

(3)在springboot启动的入口类加入一个注解@EnableEurekaServer,即可将该项目作为服务注册中心

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70

(4)在resources下创建配置文件application.properties,里面添加如下内容

  1. #不向注册中心注册自己
  2. eureka.client.register-with-eureka=false
  3. #不需要检索服务
  4. eureka.client.fetch-registry=false
  5. #eureka的注册中心地址
  6. eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 1(5)登录http:localhost:8003可以看到Eureka登录页

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 2

现在注册中心还看不到任何一个应用,需要将spring-cloud-a、spring-cloud-b注册进来。

三、把服务注册到注册中心

(1)spring-cloud-a、spring-cloud-b的pom.xml里添加spring-cloud-eureka一样的配置

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-eureka-server</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>ch.qos.logback</groupId>
  8. <artifactId>logback-classic</artifactId>
  9. <version>1.2.1</version>
  10. </dependency>
  11. </dependencies>
  12. <dependencyManagement>
  13. <dependencies>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-dependencies</artifactId>
  17. <version>Brixton.RELEASE</version>
  18. <type>pom</type>
  19. <scope>import</scope>
  20. </dependency>
  21. </dependencies>
  22. </dependencyManagement>

(2)在resources下创建配置文件application.properties,里面添加如下内容

  1. #eureka的注册中心地址
  2. eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/
  3. #注册进eureka的名字
  4. spring.application.name=spring-cloud-b

(3)在springboot启动的入口类加入一个注解@EnableDiscoveryClient,即可完成注册服务。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 3

(4)登录eureka注册中心,能看到新加入的两个服务

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 4

四、远程调用服务

远程调用服务的方式有两种,分别为restTemplate和feign

restTemplate:主要通过ribbon使客户端做到负载均衡,类似nginx反向代理,需要手动启动

feign:可以简化客户端代码,默认集成了ribbon实现了负载均衡的效果,并和Eureka结合,自动启动

(1)使用restTemplate调用服务(在需要调用的系统里添加restTemplate,这里是我b系统调用a系统的方法,所以在b系统里添加)

a、b两个系统的pom.xml里都添加依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-ribbon</artifactId>
  4. </dependency>

在b系统的springboot启动的入口类添加如下代码,开启客户端的负载均衡

  1. @Bean
  2. @LoadBalanced
  3. public RestTemplate restTemplate() {
  4. return new RestTemplate();
  5. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 5

在b系统里添加controller测试类

  1. package springboot.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. import org.springframework.web.client.RestTemplate;
  5. import javax.annotation.Resource;
  6. @RestController
  7. public class TestController {
  8. @Resource
  9. private RestTemplate restTemplate;
  10. @RequestMapping(value = "/getStr")
  11. public String getStr(){
  12. //调用远程服务,这里是使用应用名spring-cloud-b,在application.properties里配置
  13. String str = restTemplate.getForObject("http://spring-cloud-a/getStr",String.class);
  14. return str;
  15. }
  16. }

在a系统里添加controller测试类

  1. package springboot.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. @RestController
  5. public class TestController {
  6. @RequestMapping(value = "/getStr")
  7. public String getStr(){
  8. return "spring-cloud-a";
  9. }
  10. }

访问b系统的getStr方法,调用成功

20200705164050697.png

(2)使用feign调用服务

a、b两个系统的pom.xml里都添加依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-feign</artifactId>
  4. </dependency>

在springboot启动的入口类加入一个注解@EnableFeignClients(在需要调用的系统里添加@EnableFeignClients,这里是我b系统调用a系统的方法,所以在b系统里添加)

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 6

在b系统里添加测试接口

  1. package springboot.controller;
  2. import org.springframework.cloud.netflix.feign.FeignClient;
  3. import org.springframework.stereotype.Service;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. @Service
  6. @FeignClient("spring-cloud-a")
  7. public interface SpringCloudAFeign {
  8. @RequestMapping(value = "/getStr")
  9. public String getStr();
  10. }

在b系统里修改测试controller

  1. package springboot.controller;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4. import javax.annotation.Resource;
  5. @RestController
  6. public class TestController {
  7. @Resource
  8. private SpringCloudAFeign springCloudAFeign;
  9. @RequestMapping("/getStr")
  10. public String getStr(){
  11. String str = springCloudAFeign.getStr();
  12. return str;
  13. }
  14. }

这里我启动报如下的错,查看后发现时spring boot版本和spring cloud版本不兼容导致,我用的spring boot版本为1.4.0.RELEASE,spring cloud版本为Brixton.RELEASE

  1. org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.cloud.netflix.feign.FeignClient] must be declared as an @AliasFor [serviceId], not [name].

spring boot 跟 spring cloud的版本对应关系如下




























spring boot spring cloud
Spring Boot 1.2.x Angel
Spring Boot 1.3.x Brixton
Spring Boot 1.4.x Camden
Spring Boot 1.5.x Dalston和Edgware
Spring Boot 2.0.x Finchley

spring cloud版本改为Camden.RELEASE解决

启动后访问b系统的getStr方法,调用成功

20200705174047716.png

五、路由网关(ZUUL)

因为不同系统之间的访问因为地址不同可能会出现跨域问题,spring cloud提供了解决方案路由网关ZUUL

(1)新建一个springboot项目名为spring-cloud-zuul,端口号为8004

(2)在pom.xml中添加zuul的依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-eureka-server</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>ch.qos.logback</groupId>
  8. <artifactId>logback-classic</artifactId>
  9. <version>1.2.1</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-starter-zuul</artifactId>
  14. </dependency>
  15. </dependencies>
  16. <dependencyManagement>
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.springframework.cloud</groupId>
  20. <artifactId>spring-cloud-dependencies</artifactId>
  21. <version>Brixton.RELEASE</version>
  22. <type>pom</type>
  23. <scope>import</scope>
  24. </dependency>
  25. </dependencies>
  26. </dependencyManagement>

(3)在springboot启动的入口类加入一个注解@EnableZuulProxy

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MjYwMzE1_size_16_color_FFFFFF_t_70 7

(4)在resources下创建配置文件application.properties,里面添加如下内容。我这里刚开始没添加超时时间设置,访问会报超时的错

  1. #eureka的注册中心地址
  2. eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/
  3. #注册进eureka的名字
  4. spring.application.name=spring-cloud-zuul
  5. #zuul路由转发spring-cloud-a转发到service_a
  6. zuul.routes.spring-cloud-a.path=/service_a/**
  7. zuul.routes.spring-cloud-a.service-id=spring-cloud-a
  8. #zuul路由转发spring-cloud-b转发到service_b
  9. zuul.routes.spring-cloud-b.path=/service_b/**
  10. zuul.routes.spring-cloud-b.service-id=spring-cloud-b
  11. #ribbon的超时时间设置
  12. ribbon.ReadTimeout=3000
  13. ribbon.ConnectTimeout=3000
  14. #zuul的超时时间设置
  15. zuul.host.connect-timeout-millis=3000
  16. zuul.host.socket-timeout-millis=3000
  17. #hystrix的超时时间设置
  18. hystrix.command.default.execution.isolation.thread.timeout-in-milliseconds=3000

(5)访问转发后的b系统的getStr方法,调用成功

20200705190544122.png

发表评论

表情:
评论列表 (有 0 条评论,95人围观)

还没有评论,来说两句吧...

相关阅读