1.Spring Cloud简介
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装,屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
2.Spring Cloud使用示例
工具列表:IDEA、Maven
项目构成:服务注册中心、服务提供者、服务消费者。
项目结构如下:
2.1.创建空白工程
为了方便管理,我们创建一个空白工程,我们例子中的3个项目都作为这个空白工程的子模块创建。
主要步骤如下:
1.File->New->Project,选择Maven
2.点击Next,输入相关信息
3.创建完成后把其它文件都删掉,只保留pom.xml即可。
2.2.服务注册发现模块
此模块对应项目结构中的demo-eureka
主要步骤如下:
1.在主工程上File->New->Module,选择Spring Initializr
2.点击Next,输入模块信息
3.点击Next,选择Cloud Discovery->Eureka Server
4.生成的pom文件部分配置
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
5.启动类,加上@EnableEurekaServer注解
@SpringBootApplication
@EnableEurekaServer
public class DemoEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(DemoEurekaApplication.class, args);
}
}
6.配置文件application.properties添加如下配置
# 端口号
server.port=8000
# 关闭自我保护
eureka.server.enable-self-preservation=false
# 清理服务器时间间隔[5s]
eureka.server.eviction-interval-timer-in-ms=5000
# 主机名
eureka.instance.hostname=localhost
# 是否将自己作为客户端注册到Eureka Server[当前模块只是作为Eureka Server服务端所以设为false]
eureka.client.register-with-eureka=false
# 是否从Eureka Server获取注册信息[当前是单点的Eureka Server所以不需要同步其它节点的数据]
eureka.client.fetch-registry=false
# Eureka Server[查询注册服务]地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
2.3.服务提供者模块
此模块对应项目结构中的demo-provider
1.创建过程不再赘述,与创建服务注册发现模块的区别是,依赖中选择:
- Web->Web
- Cloud Discovery->Eureka Server
2.pom文件依赖配置如下
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
3.启动类,加上@EnableDiscoveryClient,表示其作为服务发现客户端
@SpringBootApplication
@EnableDiscoveryClient
public class DemoProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProviderApplication.class, args);
}
}
4.application.properties添加如下配置
# 端口号
server.port=8010
# 应用名称
spring.application.name=provider
# Eureka Server服务器地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
5.定义MyController类
@RestController
public class MyController {
@RequestMapping(value = "/info", method = RequestMethod.GET)
public String getDefaultInfo() {
try {
//休眠2秒,测试超时服务熔断[直接关闭服务提供者亦可]
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello provider";
}
@RequestMapping(value = "/info/{name}", method = RequestMethod.POST)
public String getInfo(@PathVariable String name) {
return "Hello " + name;
}
}
2.3.服务消费者模块
此模块对应项目结构中的demo-consumer
1.创建过程不再赘述,与创建服务注册发现模块的区别是,依赖中选择:
- Web->Web
- Cloud Discovery->Eureka Server
- Cloud Routing->Feign
2.pom文件依赖配置如下
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
3.启动类,加上@EnableFeignClients和@EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DemoConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(DemoConsumerApplication.class, args);
}
}
4.application.properties添加如下配置
# 端口号
server.port=8020
# 应用名称
spring.application.name=consumer
# Eureka Server服务器地址
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
# 高版本spring-cloud-openfeign请求分为两层,先ribbon控制,后hystrix控制.
# Ribbon请求连接的超时时间
ribbon.ConnectionTimeout=5000
# Ribbon请求处理的超时时间.
ribbon.ReadTimeout=5000
# 设置服务熔断超时时间[默认1s]
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
# 开启hystrix以支持服务熔断[高版本默认false关闭],如果置为false,则请求超时交给ribbon控制.
# feign.hystrix.enabled=true
5.定义服务接口类InfoClient,作为调用远程服务的本地入口
/**
* FeignClient配置说明
* 1.name:被调用的服务应用名称
* 2.fallback: InfoFallBack作为熔断实现,当请求provider失败时调用其中的方法
* 3.configuration: feign配置
*/
@FeignClient(name = "provider", fallback = InfoFallBack.class, configuration = MyFeignConfig.class)
public interface InfoClient {
@RequestMapping(value = "/info", method = RequestMethod.GET)
String getDefaultInfo();
@RequestMapping(value = "/info/{name}", method = RequestMethod.POST)
String getInfo(@PathVariable("name") String name);
}
6.定义熔断类InfoFallBack,如果远程服务无法成功请求,则调用指定的本地逻辑方法
@Component
public class InfoFallBack implements InfoClient {
@Override
public String getDefaultInfo() {
return "fallback info";
}
@Override
public String getInfo(String name) {
return "fallback default info";
}
}
7.定义feign配置类MyFeignConfig
@Configuration
public class MyFeignConfig {
/**
* Feign打印日志等级
*
* @return
*/
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
注意这里的Logger用的是feign下面的,需要引入
import feign.Logger;
8.定义服务调用类ConsumerController,通过本地方法入口调用远程服务
@RestController
public class ConsumerController {
@Autowired
private InfoClient infoClient;
@RequestMapping(value = "/call/info", method = RequestMethod.GET)
public String consumerInfo(){
return infoClient.getDefaultInfo();
}
@RequestMapping(value = "/call/info/{name}", method = RequestMethod.GET)
public String consumerInfo(@PathVariable String name){
return infoClient.getInfo(name);
}
}
2.4.测试
1.依次启动demo-eureka、demo-provider、demo-consumer
2.访问http://127.0.0.1:8000/
你会看到我们的提供者、消费者都已经注册
3.访问消费者
- http://127.0.0.1:8020/call/info/
- http://127.0.0.1:8020/call/info/wander
你会看到消费者成功访问了提供者的API并返回了正确的结果。
4.测试服务熔断,application.properties配置修改如下
# 设置服务熔断超时时间[默认1s]
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
# 开启hystrix以支持服务熔断[高版本默认false关闭],如果置为false,则请求超时交给ribbon控制.
feign.hystrix.enabled=true