LD is tigger forever,CG are not brothers forever, throw the pot and shine.
Modesty is not false, solid is not naive, treacherous but not deceitful, stay with good people, and stay away from poor people.
talk is cheap, show others the code,Keep progress,make a better result.
目录
概述
架构特性
设计思路
实现思路分析
一 项目准备 pom文件.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hanergy</groupId>
<artifactId>out</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zuul-server</name>
<description>zuul project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
<docker.image.prefix>zuul-server</docker.image.prefix>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.10</druid.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 数据库相关jar包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<!-- zipkin链路追踪 包含了sleuth包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!--配置中心客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>zuul-server</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- tag::plugin[] -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.3</version>
<!--将插件绑定在某个phase执行-->
<executions>
<execution>
<id>build-image</id>
<!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package ,就会自动执行mvn docker:build-->
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>${docker.image.prefix}</imageName>
<imageTags>
<imageTag>latest</imageTag>
</imageTags>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<dockerHost>http://39.106.68.199:2375</dockerHost>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.bootstrap.yml:
spring:
application:
name: oa
# 配置中心
cloud:
config:
#discovery:
#第一种集成配置中心的方式,通过config的service-id映射 这种方式本地环境无法连接阿里配置中心服务 因为映射的是内网ip 本地无法访问
# 配置中心注册名称 默认去{label}/getway-{profile}.yml文件注册中心命名规则{name}-{profile}.yml /{name}/{profile}/{label}
#service-id: springcloud-config # 配置中心注册名称 默认去{label}节点读取order-{profile}.yml文件
#enabled: true
# 后缀 dev|prod
profile: dev
# dev|master分支,建议使用它区分生产、测试环境
label: dev
# 第二种集成配置中心的方式,这里写配置中心服务的地址信息
uri: http://39.106.68.199:8991
配置中心配置文件:
eureka:
client:
serviceUrl:
defaultZone: http://39.106.68.199:8761/eureka/,http://39.106.68.199:8762/eureka/,http://39.106.68.199:8763/eureka/
hystrix:
enabled: true
instance:
hostname: ${spring.cloud.client.ip-address}
instance-id: ${spring.cloud.client.ip-address}:8002
prefer-ip-address: true
feign:
client:
config:
default:
connectTimeout: 4000
readTimeout: 4000
hystrix:
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
logging:
level:
com:
hanergy:
activiti:
data: debug
io:
swagger:
models:
parameters:
AbstractSerializableParameter: error
org:
springframework:
boot:
autoconfigure: ERROR
management:
endpoints:
web:
exposure:
include: '*'
mybatis-plus:
configuration:
cache-enabled: false
call-setters-on-nulls: true
map-underscore-to-camel-case: true
global-config:
db-config:
field-strategy: NOT_NULL
id-type: input
logic-delete-value: -1
logic-not-delete-value: 0
refresh: true
mapper-locations: classpath:mybatis/*.xml
typeAliasesPackage: com.hanergy.out.entity
server:
connection-timeout: 5000ms
port: 8002
tomcat:
max-threads: 1000
min-spare-threads: 30
uri-encoding: UTF-8
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
password: ArA8IyYFmQcrlxJP
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://rm-2zezdhr94r3t4et671o.mysql.rds.aliyuncs.com:3306/oa?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC
username: root
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
mvc:
static-path-pattern: /static/**
throw-exception-if-no-handler-found: true
redis:
host: r-2zepy3qy5wj310jplipd.redis.rds.aliyuncs.com
open: false
password: X9fMp!guajqOI#Y7
port: 6379
resources:
add-mappings: false
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
sleuth:
sampler:
probability: 0.1
zipkin:
base-url: http://39.106.68.199:9411/
locator:
discovery:
enabled: true
启动类添加注解:
package com.hanergy.out;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableSwagger2
@EnableFeignClients //feign
@EnableDiscoveryClient
@EnableCircuitBreaker // 熔断器注解
@EnableHystrixDashboard // 断路器Dashboard监控仪表盘
@MapperScan(basePackages = {"com.hanergy.out.dao"})
public class HanergyOutApplication {
public static void main(String[] args) {
SpringApplication.run(HanergyOutApplication.class, args);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
/**
* corsFilter
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
二。服务间调用
调用方:
/**
* name是注册中心注册的名称, 也可以通过url来进行调用,使用url的时候需要配置value
* fallback指定hystrix熔断操作
*/
//@FeignClient(url = "39.106.68.199:8001", value = "12",fallback = FeignClienFallback.class)
@FeignClient(name = "template",fallback = FeignClienFallback.class)
public interface FeignClientService {
@GetMapping("/v1/test/mysql")
public R mysql(@RequestParam("username")String username);
}
熔断实现:
@Service
public class FeignClienFallback implements FeignClientService {
// 这里可以写调用失败处理逻辑
@Override
public R mysql(String username) {
return R.error(-1,"error");
}
}
被调用方不用做修改:
package com.hanergy.out.controller;
import com.hanergy.out.entity.SysUser;
import com.hanergy.out.service.ISysUserService;
import com.hanergy.out.utils.R;
import com.netflix.discovery.converters.Auto;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @ClassName TestController
* @Description
* @Auto HANLIDONG
* @Date 2019-7-12 9:51)
*/
@RestController
@RequestMapping("/v1/test")
public class TestController {
Logger log = LoggerFactory.getLogger(TestController.class);
@Autowired
private ISysUserService sysUserService;
@ApiOperation(value="测试",notes="测试信息")
@ApiImplicitParams({
@ApiImplicitParam(name="test",value="测试",required=true,paramType="query")
})
@GetMapping("/test")
public R test(@RequestParam("test")String test){
log.info(test);
return R.ok();
}
@ApiOperation(value="测试",notes="测试信息")
@ApiImplicitParams({
@ApiImplicitParam(name="test",value="测试",required=true,paramType="query")
})
@GetMapping("/mysql")
public R mysql(@RequestParam("username")String username) throws InterruptedException {
log.info(username);
// Thread.sleep(5000);
List<SysUser> sysUsers = sysUserService.findByLikeUserName(username);
return R.ok(1,sysUsers);
}
}
相关工具如下:
实验效果:(解决思路)
分析:
小结:
主要讲述了一些Hystrix实现自定义接口降级,里面有许多不足,请大家指正~
参考资料和推荐阅读
1.链接: 参考资料.