Spring cloud入门
2017-07-13 14:31
405 查看
spring cloud生态
spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、事件总线等等服务的注册与发现(Eureka)
pom引入包<!--eureka server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>
启动一个服务注册中心,注解@EnableEurekaServer
@EnableEurekaServer @SpringBootApplication public class EurekaserverApplication { public static void main(String[] args) { SpringApplication.run(EurekaserverApplication.class, args); } }
配置文件application.yml
server: port: 8761 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/[/code]Eureka Ha
配置文件peer1:spring: application: name: eureka-ha server: port: 8761 eureka: instance: hostname: peer1 client: serviceUrl: defaultZone: http://peer2:8762/eureka/[/code]
配置文件peer2:spring: application: name: eureka-ha server: port: 8762 eureka: instance: hostname: peer2 client: serviceUrl: defaultZone: http://peer1:8761/eureka/[/code]
启动用不同配置文件就完成集群其他
## 失效剔除 60s检测一次,超过90s没心跳 ## 自我保护 ## 触发:心跳失败比例 15分钟内<85% eureka.server.enable-self-preservation=false ## 配置元数据 eureka.instance.metadataMap.zone=shanghai eureka.instance.key=value ## 随机数 ${random.int} server.port=${random.int[1000,1999]} ## 自定义url management.context-path=/hello eureka.instance.statusPageUrlPath=${management.context-path}/info eureka.instance.healthCheckUrlPath=${management.context-path}/health ## 健康检查交给/health 引入spring-boot-starter-actuator eureka.client.healthcheck.enabled=true ## 其他配置 preferIpAddress nonSecurePort securePort noneSecurePortEnabled securePortEnabled appname hostname创建服务提供者 (Eureka client)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
controller@RestController public class UserController { @Autowired private UserDao userDao; @GetMapping("/user/{id}") public User get(@PathVariable Long id) { return userDao.findOne(id); } }
配置文件application.ymlserver: port: 7900 spring: application: name: provider eureka: client: healthcheck: enabled: true service-url: defaultZone: http://localhost:8761/eureka/[/code]
注解为服务发现(服务提供者)、Eureka客户端@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
其他## 是否注册eureka eureka.client.register-with-eureka=true ## 获取服务间隔 eureka.client.register-fetch-interval-seconds=30 ## 设置region eureka.client.region ## 配置元数据 eureka.instance.metadataMap.zone=shanghai eureka.instance.key=value ## DiscoveryClient类 这个类用于帮助与Eureka Server互相协作。 Eureka Client负责了下面的任务: - 向Eureka Server注册服务实例 - 向Eureka Server为租约续期 - 当服务关闭期间,向Eureka Server取消租约 - 查询Eureka Server中的服务实例列表创建服务消费者(ribbon)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
application.ymlserver: port: 8900 spring: application: name: ribbon eureka: client: service-url: defaultZone: http://localhost:8761/eureka/[/code]
通过@EnableDiscoveryClient向服务中心注册
注册了一个bean: restTemplate
通过@ LoadBalanced注册表明,这个restRemplate是负载均衡的@SpringBootApplication @EnableDiscoveryClient public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }LoadBalancerClient
public interface LoadBalancerClient { ServiceInstance choose(String serviceId); <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException; URI reconstructURI(ServiceInstance instance, URI original); }
ServiceInstance choose(String serviceId)
根据传入的服务名serviceId,从负载均衡器中挑选一个对应服务的实例。
T execute(String serviceId, LoadBalancerRequest request) throws IOException
使用从负载均衡器中挑选出的服务实例来执行请求内容。
URI reconstructURI(ServiceInstance instance, URI original)
为系统构建一个合适的“host:port”形式的URI。
在分布式系统中,我们使用逻辑上的服务名称作为host来构建URI
(替代服务实例的“host:port”形式)进行请求,
比如:http://myservice/path/to/service。
在该操作的定义中,
前者ServiceInstance对象是带有host和port的具体服务实例,
而后者URI对象则是使用逻辑服务名定义为host的URI,
而返回的URI内容则是通过ServiceInstance的服务实例详情拼接出的具体“host:post”形式的请求地址。ILoadBalancer
public interface ILoadBalancer { public void addServers(List<Server> newServers); public Server chooseServer(Object key); public void markServerDown(Server server); public List<Server> getReachableServers(); public List<Server> getAllServers(); }
addServers
向负载均衡器中维护的实例列表增加服务实例。
chooseServer
通过某种策略,从负载均衡器中挑选出一个具体的服务实例。
markServerDown
用来通知和标识负载均衡器中某个具体实例已经停止服务,不然负载均衡器在下一次获取服务实例清单前都会认为服务实例均是正常服务的。
getReachableServers
获取当前正常服务的实例列表。
getAllServers
获取所有已知的服务实例列表,包括正常服务和停止服务的实例。默认实现
IClientConfig -> DefaultClientConfigImpl IRule -> ZoneAvoidanceRule ILoadBalancer -> ZoneAwareLoadBalancer IPing -> NIWSDicoveryPing ServerList -> DomainExtractingServerList ServerList<Server> -> ZonePreferenceServerListFilter重试配置
spring.cloud.loadbalance.retry.enabled=true xxx.ribbon.ConnectTimeout=250 ##连接超时 xxx.ribbon.ReadTimeout=1000 ## 读超时 xxx.ribbon.OkToRetryOnAllOperations=true ##所有请求进行重试 xxx.ribbon.MaxAutoRetriesNextServer=2 ##切换实例重试次数 xxx.ribbon.MaxAutoRetries=1 ##当前实例重试次数 注意: hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000 ##ribbon超时必须大于hystrix 要不然不触发断路器(Hystrix)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
Application增加注解@EnableCircuitBreaker@SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker public class RibbonApplication { .....
加上@HystrixCommand,并指定fallbackMethod方法。@GetMapping("/get/{id}") @HystrixCommand(fallbackMethod = "getFailback") public User get(@PathVariable Long id) { return restTemplate.getForObject("http://PROVIDER/user/" + id, User.class); } public User getFailback(@PathVariable Long id) { User user = new User(); user.setId(id); return user; }
HystrixCommand 表明该方法为hystrix包裹,可以对依赖服务进行隔离、降级、快速失败、快速重试等等hystrix相关功能
该注解属性较多,下面讲解其中几个
fallbackMethod 降级方法
commandProperties 普通配置属性,可以配置HystrixCommand对应属性,例如采用线程池还是信号量隔离、熔断器熔断规则等等
ignoreExceptions 忽略的异常,默认HystrixBadRequestException不计入失败
groupKey() 组名称,默认使用类名称
commandKey 命令名称,默认使用方法名断路器执行逻辑
1.创建 HystrixCommand 或 HystrixObservableCommand
2.命令执行
execute()同步
queue() 异步
observe() 返回observable对象
toObservable() 冷observable对象
3.结果是否缓存 -> observable
4.断路器是否打开 -> fallback
5.线程池/请求队列/信号量 是否占满
6.HystrixObservableCommand.construct() 返回observable对象发射多个结果
或onError发送错误通知
或 HystrixCommand.run()
返回单一结果 或异常 onCompleted通知
7.计算断路器的健康度
8.fallback处理
9.返回成功响应常用线程配置
若不设置组名,相同的组共用一个线程池 设置了线程池名,相同的公用一个线程池 @HystrixCommand(fallbackMethod = "getFailback",threadPoolProperties = { @HystrixProperty(name = "coreSize",value = "5") }) coreSize 最大并发 默认10 maxQueueSize 队列大小 -1为linkedQueue metrics.rollingStats.timeInMilliseconds 滚动时间窗口 单位毫秒 默认10秒 metrics.rollingStats.numBuckets 滚动时间窗分几个桶 默认10个桶全局配置
hystrix.command.default.execution.isolation.strategy 默认THREAD 可选SEMAPHORE hystrix.command.default.execution.timeout.enabled 默认true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 默认1000毫秒 hystrix.command.default.execution.isolation.thread.interruptOnTimeout 超时是否中断 hystrix.command.default.execution.isolation.maxConcurrentRequests 默认10 当为信号量时,设置并发请求数 hystrix.command.default.circuitBreaker.enabled 默认true. 请求失败时,是否试用断路器跟踪健康指标和熔断请求 hystrix.command.default.circuitBreaker.requestVolumeThreshold 默认20 滚动窗口内,断路器熔断最小请求数 hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds 断路器打开后休眠时间,休眠后“半开”状态 hystrix.command.default.circuitBreaker.errorThresholdPercentage 默认50 滚动时间窗中,请求数达到requestVolumeThreshold,失败比例超过errorThresholdPercentage,熔断打开 hystrix.command.default.metrics.rollingStats.timeInMilliseconds 默认10000(毫秒) 设置滚动窗口时间长度 hystrix.command.default.metrics.rollingStats.numBuckets 默认10 时间窗口内划分桶的数量 hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds 默认60000 (毫秒) 百分位统计的滚动窗口的持续时间 hystrix.command.default.metrics.rollingPercentile.numBuckets 默认6 百分位统计的窗口桶的数量 hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds 默认500(毫秒) 采集影响断路器状态的监控快照间隔时间 hystrix.command.default.metrics.rollingPercentile.bucketSize 默认500 每个桶保留的执行次数 hystrix.threadpool.default.coreSize 默认10 最大并发数 hystrix.threadpool.default.maxQueueSize 默认-1 队列大小 -1为linkedQueue hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds 默认10000(毫秒) 滚动时间窗口 hystrix.threadpool.default.metrics.rollingStats.numBuckets 默认10 滚动时间窗分几个桶声明式服务消费者(Feign)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
配置eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8765 spring: application: name: service-feign
注解@EnableFeignClients来开启feign@SpringBootApplication @EnableEurekaClient @EnableFeignClients public class FeignApp { public static void main(String[] args) { SpringApplication.run(FeignApp.class, args); } }
定义一个feign接口类,通过@ FeignClient(“服务名”),来指定调用哪个服务@FeignClient(name = "provider") public interface UserRemote { @RequestMapping(value = "/user/{id}",method = RequestMethod.GET) User get(@PathVariable("id") Long id); }
web层的controller@RestController public class UserController { @Autowired private UserRemote userRemote; @GetMapping("/get/{id}") public User get(@PathVariable Long id) { return userRemote.get(id); } }支持hystrix
配置文件增加feign.hystrix.enabled=true
修改声明@FeignClient(name = "provider",fallback = UserRemoteFallback.class) public interface UserRemote { @RequestMapping(value = "/user/{id}",method = RequestMethod.GET) User get(@PathVariable("id") Long id); }
fallback类@Component public class UserRemoteFallback implements UserRemote { @Override public User get(Long id) { System.out.println("error"); User user = new User(); user.setId(id); return user; } }其他配置
## 指定服务配置ribbon PROVIDER.ribbon.ConnectTimeout=500 PROVIDER.ribbon.ReadTimeout=5000 PROVIDER.ribbon.OkToRetryOnAllOperations=true PROVIDER.ribbon.MaxAutoRetriesNextServer=2 PROVIDER.ribbon.MaxAutoRetries=1 ## 请求压缩 feign.compression.request.enabled=true feign.compression.request.mimetypes=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048 feign.compression.response.enabled=true ## 日志级别 NONE BASIC 请求方法、url、响应码、执行时间 HEADERS BASE级别+请求头、响应头 FULL 所有请求与明细,包含请求头请求体、元数据 @Bean Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; }配置中心(Spring Cloud Config)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
配置文件application.ymlserver: port: 7950 spring: application: name: config-server cloud: config: server: git: uri: http://git.oschina.net/IMZLF/spring-config # 配置Git仓库的地址 username: # Git仓库的账号 password: # Git仓库的密码 search-paths: - foo #路径 - bar #路径 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/[/code]
Application注解@EnableConfigServer@SpringBootApplication @EnableConfigServer @EnableEurekaClient public class ConfigServerEurekaApp { public static void main(String[] args) { SpringApplication.run(ConfigServerEurekaApp.class, args); } }
获取git上的资源信息遵循如下规则:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
application : 表示应用名称,在client中通过spring.config.name配置
profile : 表示获取指定环境下配置,例如开发环境、测试环境、生产环境 默认值default,实际开发中可以是 dev、test、demo、production等
label : git标签,默认值master
如果application名称为foo,则可以采用如下方式访问:http://localhost:8888/foo/default http://localhost:8888/foo/development[/code]
只要是按照上面的规则配置即可访问.client的改造
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
增加配置文件bootstrap.ymlspring: application: name: foo # 对应config server所获取的配置文件的{application} cloud: config: profile: dev label: master discovery: enabled: true service-id: config-server
注解@RefreshScope,引用配置属性@RefreshScope public class UserController { @Value("${profile}") private String profile; @GetMapping("/profile") public String profile() { return this.profile; }
测试http://localhost:7900/profile
更新重新获取配置http://localhost:7900/refresh路由网关(zuul)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>
Applicaton注解@EnableZuulProxy,开启zuul@SpringBootApplication @EnableZuulProxy public class ZuulApp { public static void main(String[] args) { SpringApplication.run(ZuulApp.class,args); } }
application.yml配置文件server: port: 7920 spring: application: name: zuul eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ zuul: ignoredServices: '*' routes: provider: /p/** ribbon: /r/** host: max-total-connections: 200 max-per-route-connections: 20
统一由zuul访问http://localhost:7920/p/user/1 http://localhost:7920/r/get/1[/code]ZuulFilter
filterOrder:filter执行顺序,通过数字指定
shouldFilter:filter是否需要执行 true执行 false 不执行
run : filter具体逻辑
filterType :filter类型,分为以下几种
pre : 请求执行之前filter
route : 处理请求,进行路由
post : 请求处理完成后执行的filter
error : 出现错误时执行的filter
zuulFilter简单实现public class MyFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); String host = request.getRemoteHost(); System.out.println(host+request.getRequestURI()); return null; } }Hystrix Dashboard (断路器: 仪表盘)
引入包<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
@EnableHystrixDashboard注解,开启hystrixDashboard@EnableEurekaClient @EnableHystrixDashboard public class DashBoardApplication { ...
打开浏览器:访问http://localhost:6900/hystrix
输入http://localhost:8900/hystrix.stream,点击monitor断路器聚合监控(Hystrix Turbine)
看单个的Hystrix Dashboard的数据并没有什么多大的价值,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbine。
引入包<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
启动类注解@EnableTurbine@SpringBootApplication @EnableTurbine public class TurbineApplication { public static void main(String[] args) { SpringApplication.run(TurbineApplication.class, args); } }
application.yml配置server: port: 6900 spring: application: name: turbine eureka: client: healthcheck: enabled: true service-url: defaultZone: http://localhost:8761/eureka/ turbine: aggregator: clusterConfig: default appConfig: ribbon,feign,zuul clusterNameExpression: new String("default")
监控turbine流打开:http://localhost:6900/hystrix,输入监控流localhost:6900/turbine.stream服务链路追踪(Spring Cloud Sleuth)
引入包<dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> </dependency>
application.yml配置server: port: 7960 spring: application: name: sleuh-zipkinclient改造
application.yml配置zipkin地址spring: zipkin: base-url: http://localhost:7960[/code]
zipkin地址http://localhost:7960
相关文章推荐
- spring clound 之 springcloud config 入门
- Spring Cloud 3:Spring Boot快速入门
- spring cloud 入门实践系列 - eureka
- Spring Cloud 入门教程(二): 配置管理
- Spring Cloud 入门教程(一): 服务注册
- springcloud(第一篇)springcloud config 入门
- Spring Cloud入门教程(二):客户端负载均衡(Ribbon)
- Spring Cloud Eureka 入门 (二)服务提供者详解
- Spring Cloud Eureka 入门 (二)服务提供者详解
- Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务
- spring cloud入门基础
- Spring Cloud入门3——API Gateway
- Spring Cloud入门2——配置中心Config
- Spring Cloud Eureka 入门 (三)服务消费者详解
- Spring Cloud实战微服务入门
- spring cloud config 入门
- Spring Cloud config之一:分布式配置中心入门介绍
- Java - Struts框架教程 Hibernate框架教程 Spring框架入门教程(新版) sping mvc spring boot spring cloud Mybatis
- spring cloud 入门实践系列 - feign
- 对于Spring Cloud Feign入门示例的一点思考