父工程
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifcatId>spring-boot-stater-parent</artifactId>
<version>2.0.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-stater-web</artifactId>
</dependency>
<denpendency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</denpendency>
<denpendency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</denpendency>
<denpendency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</denpendency>
<denpendency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</denpendency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-denpendencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子工程
eurekaserver
pom.xml
<artifactId>eurkaserver</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8761
eureka:
client:
register-with-eurka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
- eureka.client.register-with-eurka
- 是否将当前eureka server服务当作客户端注册
- eureka.client.fetch-registry
- 是否获取其他eureka server服务数据
- eureka.client.service-url
- 注册中心访问地址
启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication{
public static void main(String[] agrs){
SpringApplication.run(EurekaServerApplication.class,args);
}
}
eurekaclient
provider
pom.xml
<artifactId>eurkaserver</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8010
spring:
application:
name: provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
- eurkea.instance.prefer-ip-address
- 是否将当前服务注册到eureka server
启动类
@SpringBootApplication
public class ProviderApplication{
public static void main(String[] args){
SpringApplication.run(ProviderApplication.class,args);
}
}
controller
@RestController
public class StudentController{
@Autowired
private StudentService studentService;
@RequestMapping("/student/findAll")
public List<Student> findAll(){
return studnetServce.finaAll();
}
}
consumer
pom.xml
<artifactId>eurkaserver</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8020
spring:
application:
name: consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
- eurkea.instance.prefer-ip-address
- 是否将当前服务注册到eureka server
启动类
@SpringBootApplication
public class ConsumerApplication{
public static void main(String[] args){
SpringApplication.run(ConsumerApplication.class,args);
}
}
controller
@RestController
public class ConsumerController{
@Autowired
private StudentService studentService;
@RequestMapping("/customer/findAll")
public List<Student> findAll(){
// 利用resttemplate调用Provider提供的接口
return studnetServce.finaAll();
}
}
网关
Zuul
pom.xml
<artifactId>zuul</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-zuul</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8030
spring:
application:
name: gateway
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
zuul:
routes:
provider: /provider/**
- zuul.routes.provider
- 为provider映射
启动类
@SpringBootApplication
@EnableZuulProxy
@EnableAutoConfiguration
public class ZuulApplication{
public static void main(String[] args){
SpringApplication.run(ZuulApplication.class,args);
}
}
Ribbon负载均衡
spring cloud ribbon
- ribbon
- 基于netfix ribbon
- ribbon + restTemplate
- HTTP请求负载均衡
- 轮询
- @LoadBalanced
- 随机
- 加权轮询
- 加权随机
- 轮询
- 结合Eureka
pom.xml
<artifactId>ribbon</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8040
spring:
application:
name: ribbon
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
启动类
@SpringBootApplication
public class RibbonApplication{
public static void main(String[] args){
SpringApplication.run(RibbonApplication.class,args);
}
}
controller
@RestController
public class RibbonController{
@Autowired
private RibbonService ribbonService;
@RequestMapping("/ribbon/findAll")
public List<Student> findAll(){
// 使用restTemplate调用服务提供者接口
return ribbonService.finaAll();
}
}
Feign声明式接口调用
spring cloud feign
- feign
- netfix提供
- ribbon+hystrix
pom.xml
<artifactId>feign</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-openfeign</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8050
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
- feign.hystrix.enabled
- 是否开启熔断器
启动类
@SpringBootApplication
@EnableFeignClients
public class FeignApplication{
public static void main(String[] args){
SpringApplication.run(FeignApplication.class,args);
}
}
controller
@RestController
public class FeignController{
@Autowired
private FeignProciderClient feignProciderClient;
@GetMapping("/ribbon/findAll")
public List<Student> findAll(){
return feignProciderClient.finaAll();
}
}
feign client
@FeignClient(value="provider",fallback=FeignError.class)
public interface FeignProciderClient{
@GetMapping("/student/findAll")
public List<Student> findAll();
}
熔断
@Component
public class FeignError implements FeignProciderClient{
public List<Student> findAll(){
return null;
}
}
容错机制
hystrix
-
设计原理
- 服务隔离机制
- 服务降级机制
- 熔断机制
- 时事监控和报警功能
- 实时配置修改功能
-
监控
- hystrix.stream
- http://ip:端口/actuator/hystrix.stream
- springboot actuator
- http://ip:端口/hystrix
- hystrix.stream
pom.xml
<artifactId>feign</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-openfeign</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.boot</groupId>
<artifactId>spring-boot-stater-actuator</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-hystrix</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-hystrix-dashboard</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8060
spring:
application:
name: hystrix
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
management:
endpoints:
web:
exposure:
include: 'hystrix.stream'
- feign.hystrix.enabled
- 是否开启熔断器
启动类
@SpringBootApplication
@EnableFeignClients
// 声明启动数据监控
@EnableCircuitBreaker
// 声明启动可视化监控
@EnableHystrixDashboard
public class HystrixApplication{
public static void main(String[] args){
SpringApplication.run(HystrixApplication.class,args);
}
}
controller
@RestController
public class HystrixController{
@Autowired
private FeignProciderClient feignProciderClient;
@GetMapping("/ribbon/findAll")
public List<Student> findAll(){
return feignProciderClient.finaAll();
}
}
feign client
@FeignClient(value="provider",fallback=FeignError.class)
public interface FeignProciderClient{
@GetMapping("/student/findAll")
public List<Student> findAll();
}
@Component
public class FeignError implements FeignProciderClient{
public List<Student> findAll(){
return null;
}
}
配置中心
- spring cloud config
- 可以将配置文件存储在本地或远程git仓库
本地配置文件系统
nativeconfigserver
pom.xml
<artifactId>nativeconfigserver</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8762
spring:
application:
name: nativeconfigserver
profiles:
active: active
cloud:
config:
server:
native:
search-locations: classpath:/shared
- spring.profiles.active
- 配置文件获取方式
- spring.cloud.config.server.native.search-locations
- 本地文件存放路径
resources/shared/configclient-dev.yml
server:
port: 8070
启动类
@SpringBootApplication
// 声明配置中心
@EnableConfigServer
public class NativeConfigServerApplication{
public static void main(String[] args){
SpringApplication.run(NativeConfigServerApplication.class,args);
}
}
nativeconfigclient
pom.xml
<artifactId>nativeconfigclient</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
bootstrap.yml
spring:
application:
name: configclient
profiles:
active: dev
cloud:
config:
uri: http://localhost:8762
fail-fast: true
- spring.profiles.active
- 配置文件获取方式
- spring.cloud.config.uri
- 本地config server 访问路径
- spring.cloud.config.fail-fast
- 设置客户端优先判断config server获取是否正常
启动类
@SpringBootApplication
public class NativeConfigClientApplication{
public static void main(String[] args){
SpringApplication.run(NativeConfigClientApplication.class,args);
}
}
远程配置文件系统
configclient.yml
- 配置文件在git上
server:
port: 8070
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: configclient
configserver
pom.xml
<artifactId>configserver</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8888
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: git路径
searchPaths: config
username: xxx
password: xxx
label: master
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
启动类
@SpringBootApplication
// 声明配置中心
@EnableConfigServer
public class ConfigServerApplication{
public static void main(String[] args){
SpringApplication.run(ConfigServerApplication.class,args);
}
}
configclient
pom.xml
<artifactId>configclient</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
bootstrap.yml
spring:
cloud:
config:
name: configclient
label: master
discovery:
enabled: true
service-id: configserver
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
- spring.cloud.config.name
- 注册到eureka server,与远程仓库配置文件名称对应
- spring.cloud.config.label
- git 分支
- spring.cloud.config.discovery.enabled
- 是否开启config服务发现支持
- spring.cloud.config.discovery.service-id
- 配置中心在erurka注册名
启动类
@SpringBootApplication
public class ConfigClientApplication{
public static void main(String[] args){
SpringApplication.run(ConfigClientApplication.class,args);
}
}
服务跟踪
spring cloud zipkin
- 监控各个微服务请求耗费时间
- zipkin server
- http://ip:端口号/zipkin
- zipkin client
zipkin server
pom.xml
<artifactId>zipkin</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-stater-web</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.9.4</version>
</dependency>
</depenedencies
application.yml
server:
port: 9090
启动类
@SpringBootApplication
// 声明启动Zipkin server
@EnableZipkinServer
public class ZipKinApplication{
public static void main(String[] args){
SpringApplication.run(ZipKinApplication.class,args);
}
}
zipkin client
pom.xml
<artifactId>zipkinclient</artifactId>
<depenedencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stater-zipkin</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframe.cloud</groupId>
<artifactId>spring-cloud-stater-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</depenedencies
application.yml
server:
port: 8090
spring:
application:
name: zipkinclinet
sleuth:
web:
client:
enable: true
sampler:
probability: 1.0
zipkin:
base-url: http://localhost:9090/
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
- spring.sleuth.web.client.enable
- 设置开启请求跟踪
- spring.sleuth.sampler.probability
- 设置采样比例,默认1.0
- spring.zipkin.base-url
- zipkin地址
启动类
@SpringBootApplication
public class ZipKinClientApplication{
public static void main(String[] args){
SpringApplication.run(ZipKinClientApplication.class,args);
}
}