搭建Spring Boot+Spring Cloud微服务

    技术2023-09-06  77

    一、先创建两个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里添加

    <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.1</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

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

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

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

     

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

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

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

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

    <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.1</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

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

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

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

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

    四、远程调用服务

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

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

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

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

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

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

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

    @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }

    在b系统里添加controller测试类

    package springboot.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController public class TestController { @Resource private RestTemplate restTemplate; @RequestMapping(value = "/getStr") public String getStr(){ //调用远程服务,这里是使用应用名spring-cloud-b,在application.properties里配置 String str = restTemplate.getForObject("http://spring-cloud-a/getStr",String.class); return str; } }

    在a系统里添加controller测试类

    package springboot.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @RequestMapping(value = "/getStr") public String getStr(){ return "spring-cloud-a"; } }

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

    (2)使用feign调用服务

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

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

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

    在b系统里添加测试接口

    package springboot.controller; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; @Service @FeignClient("spring-cloud-a") public interface SpringCloudAFeign { @RequestMapping(value = "/getStr") public String getStr(); }

    在b系统里修改测试controller

    package springboot.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private SpringCloudAFeign springCloudAFeign; @RequestMapping("/getStr") public String getStr(){ String str = springCloudAFeign.getStr(); return str; } }

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

    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 bootspring cloudSpring Boot 1.2.xAngelSpring Boot 1.3.xBrixtonSpring Boot 1.4.xCamdenSpring Boot 1.5.xDalston和EdgwareSpring Boot 2.0.xFinchley

    spring cloud版本改为Camden.RELEASE解决

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

    五、路由网关(ZUUL)

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

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

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

    <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

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

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

    #eureka的注册中心地址 eureka.client.serviceUrl.defaultZone=http://localhost:8003/eureka/ #注册进eureka的名字 spring.application.name=spring-cloud-zuul #zuul路由转发spring-cloud-a转发到service_a zuul.routes.spring-cloud-a.path=/service_a/** zuul.routes.spring-cloud-a.service-id=spring-cloud-a #zuul路由转发spring-cloud-b转发到service_b zuul.routes.spring-cloud-b.path=/service_b/** zuul.routes.spring-cloud-b.service-id=spring-cloud-b #ribbon的超时时间设置 ribbon.ReadTimeout=3000 ribbon.ConnectTimeout=3000 #zuul的超时时间设置 zuul.host.connect-timeout-millis=3000 zuul.host.socket-timeout-millis=3000 #hystrix的超时时间设置 hystrix.command.default.execution.isolation.thread.timeout-in-milliseconds=3000

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

    Processed: 0.010, SQL: 10