一、先创建两个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里添加
org.springframework.cloud
spring-cloud-starter-eureka-server
ch.qos.logback
logback-classic
1.2.1
org.springframework.cloud
spring-cloud-dependencies
Brixton.RELEASE
pom
import
(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一样的配置
org.springframework.cloud
spring-cloud-starter-eureka-server
ch.qos.logback
logback-classic
1.2.1
org.springframework.cloud
spring-cloud-dependencies
Brixton.RELEASE
pom
import
(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里都添加依赖
org.springframework.cloud
spring-cloud-starter-ribbon
在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里都添加依赖
org.springframework.cloud
spring-cloud-starter-feign
在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 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方法,调用成功
五、路由网关(ZUUL)
因为不同系统之间的访问因为地址不同可能会出现跨域问题,spring cloud提供了解决方案路由网关ZUUL
(1)新建一个springboot项目名为spring-cloud-zuul,端口号为8004
(2)在pom.xml中添加zuul的依赖
org.springframework.cloud
spring-cloud-starter-eureka-server
ch.qos.logback
logback-classic
1.2.1
org.springframework.cloud
spring-cloud-starter-zuul
org.springframework.cloud
spring-cloud-dependencies
Brixton.RELEASE
pom
import
(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方法,调用成功