# 一.基础配置
# 1.指定文件启动
#Program arguments中配置环境信息
--spring.profiles.active=eureka8767
1
2
2
# 2.返回 json 格式
@GetMapping(value = "{id}", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
1
# 3.如何复制模块?
1.先拷贝一份代码
2.修改项目名称
3.修改pom
<artifactId>springcloud-service-goods-9300</artifactId>
<name>springcloud-service-goods-9300</name>
4.修改application.yaml
5.修改GoodsApplication9300
6.删除iml
7.刷新maven
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4.配置唯一实例
#服务提供者
eureka:
client:
service-url:
defaultZone: http://eureka8767:8767/eureka/,http://eureka8768:8768/eureka/,http://eureka8769:8769/eureka/
instance:
lease-renewal-interval-in-seconds: 2 #每间隔2s,向服务端发送一次心跳,证明自己依然"存活”
lease-expiration-duration-in-seconds: 10 #告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我踢出掉
prefer-ip-address: true #告诉服务端,服务实例以IP作为链接,而不是取机器名
instance-id: springcloud-service-goods-9300 #告诉服务端,服务实例的id,id要是唯一的
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 5.端点监控
#错误的配置
management:
endpoints:
web:
exposure:
include: *
#正确的配置
management:
endpoints:
web:
exposure:
include: '*'
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 二.eureka
# 1.门户接口
@RestController
@RequestMapping("portal")
public class PortalController {
/**
* http直接访问
*/
private static final String GOODS_URL = "http://localhost:9100/kwanGoodsInfo/";
/**
* eureka访问
*/
private static final String GOODS_URL_2 = "http://goods-service/kwanGoodsInfo/";
/**
* 服务对象
*/
@Autowired
private RestTemplate restTemplate;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping(value = "{id}", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
public Result selectOne(@PathVariable Serializable id) {
//调用远程的controller
ResponseEntity<Result> forEntity = restTemplate.getForEntity(GOODS_URL_2 + id, Result.class);
return Result.ok(forEntity);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 2.配置文件
#端口号
server:
port: 8766
spring:
application:
name: eurka-server
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #由于该应用为注册中心,所以设置 为 false, 代表不向注册中心注册自己。
fetch-registry: false #由于注册中心的职责就是维护服务实例, 它并不需要去检索服务, 所以也设置为 false。
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3.高可用配置
#端口号
server:
port: 8767
spring:
application:
name: eurka-server
eureka:
instance:
hostname: eureka8767
client:
register-with-eureka: false #由于该应用为注册中心,所以设置 为 false, 代表不向注册中心注册自己。
fetch-registry: false #由于注册中心的职责就是维护服务实例, 它并不需要去检索服务, 所以也设置为 false。
serviceUrl:
defaultZone: http://eureka8768:8768/eureka/,http://eureka8769:8769/eureka/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.启动类
@EnableEurekaServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 三.feign
# 1.pom 文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
1
2
3
4
5
2
3
4
5
# 2.api 接口
@FeignClient("goods-service/kwanGoodsInfo")
public interface ComputeClient {
@RequestMapping(method = RequestMethod.GET, value = "{id}", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
Result selectOne(@PathVariable Serializable id);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3.门户请求
@RestController
@RequestMapping("feign")
public class FeignController {
@Autowired
private ComputeClient computeClient;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping(value = "{id}", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
public Result selectOne(@PathVariable Serializable id) {
//调用远程的controller
return computeClient.selectOne(id);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 4.配置文件
#端口号
server:
port: 8081
spring:
application:
name: feign-service #服务名称
#服务提供者
eureka:
client:
service-url:
defaultZone: http://eureka8767:8767/eureka/,http://eureka8768:8768/eureka/,http://eureka8769:8769/eureka/
feign:
hystrix:
enabled: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 四.ribbon
# 1.LoadBalanced
@Configuration
public class RestConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2.负载均衡配置
@Configuration
public class RestConfig {
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* 自定义负载均衡
*/
@Bean
public IRule microIrule() {
return new RandomRule();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 3.自定义负载均衡
public class MicroServiceLoadBalanceRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object key) {
ILoadBalancer lb = getLoadBalancer();
if (lb == null) {
return null;
}
List<Server> servers = lb.getReachableServers();
if (servers.isEmpty()){
return null;
}
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String uri = request.getRequestURI();
boolean specialApi = uri.startsWith("/api") ;
// /api路径优先转发到指定的机器
if(specialApi){
String ip = "192.168.2.3";
Server chooseServer = null;
for (Server server : servers) {
if (server.getHost().equals(ip)) {
chooseServer = server;
}
}
if(chooseServer == null){
chooseServer = servers.stream().findFirst().orElse(null);
}
return chooseServer;
}
return servers.get(new Random().nextInt(servers.size()));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 4.配置文件
application.yaml 配置文件:
micro-service:
ribbon:
NFLoadBalancerRuleClassName: com.mk.springcloud.gateway.loadbalance.MicroServiceLoadBalanceRule
1
2
3
2
3
#开饥饿加载,默认是懒加载,启动后就从注册中心获取服务进行缓存
ribbon.eager-load.enabled=true
#为哪些客户端开启饥饿加载,多个客户端使用逗号分隔(非必须)
ribbon.eager-load.clients=29-nacos-discovery-consumer
#读取时间
feign.client.config.default.read-timeout=1
#连接时间
feign.client.config.default.connect-timeout=1
#针对具体应用设置超时时间
feign.client.config.29-nacos-discovery-provider.read-timeout=1
#就是允许定义相同的bean对象 去覆盖原有的,默认是false
spring.main.allow-bean-definition-overriding=true
#开启feign对httpClient的支持
feign.httpclient.enabled=true
#最大连接数
feign.httpclient.max-connections=200
#每个路径的最大连接数
feign.httpclient.max-connections-per-route=50
#配置规则
ribbon:
NFLoadBalancerClassName: #ILoadBalancer 该接口实现类
NFLoadBalancerRuleClassName: #IRule 该接口实现类
NFLoadBalancerPingClassName: #Iping 该接口实现类
NIWSServerListClassName: #ServerList 该接口实现类
NIWSServerListFilterClassName: #ServiceListFilter 该接口实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 5.自定 rule
public class MicroRibbonConfig {
@Bean
public IRule microIRule(){
return new MicroServiceLoadBalanceRule();
}
}
1
2
3
4
5
6
2
3
4
5
6
@RibbonClient(name = "micro-service", configuration = MicroRibbonConfig.class)
public class RibbonClientConfig {
}
1
2
3
2
3
# 五.Hystrix
# 1.Ribbon 中引入 Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
1
2
3
4
2
3
4
@EnableFeignClients
@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
public class RibbonApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class ComputeService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "addServiceFallback")
public String addService() {
return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
}
public String addServiceFallback() {
return "error";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
public class ConsumerController {
@Autowired
private ComputeService computeService;
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add() {
return computeService.addService();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 2.Feign 使用 Hystrix
@FeignClient(value = "compute-service", fallback = ComputeClientHystrix.class)
public interface ComputeClient {
@RequestMapping(method = RequestMethod.GET, value = "/add")
Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);
}
1
2
3
4
5
6
2
3
4
5
6
@Component
public class ComputeClientHystrix implements ComputeClient {
@Override
public Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {
return -9999;
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
#开启feign开始hystrix的支持
feign:
hystrix:
enabled: true
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000 #hystrix超时时间
timeout:
enabled: true #开启hystrix超时管理
ribbon:
ReadTimeout: 2000 #请求超时时间
http:
client:
enabled: true #开启ribbon超时管理
ConnectTimeout: 2000 #连接超时时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注解方式设置超时时间
@HystrixCommand(fallbackMethod = "addServiceFallback", commandProperties = {
@HystrixProperty(name = "execution.timeout.enabled", value = "true"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "6000")
})
1
2
3
4
2
3
4
# 3.Hystrix Dashboard
<!--spring-cloud-starter-netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--springboot开发自动热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
#端口号
server:
port: 9909
spring:
application:
name: hystrix-dashboard-service #服务名称
1
2
3
4
5
6
7
2
3
4
5
6
7
#访问链接
http://localhost:9909/hystrix
1
2
2
# 4.超时配置
如果ribbon和hystrix同时开启,则以配置最小的为准。
#开启ribbon超时管理
ribbon.http.client.enabled=true
#请求超时时间
ribbon.ReadTimeout=2000
#连接超时时间
ribbon.ConnectTimeout=2000
#开启hystrix超时管理
hystrix.command.default.execution.timeout.enabled=true
#hystrix超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 六.config
# 1.pom 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
1
2
3
4
2
3
4
# 2.config 配置
#端口号
server:
port: 7001
spring:
application:
name: config-service #服务名称
cloud:
config:
server:
git:
uri: https://gitcode.net/qyj19920704/springcloud-config.git
search-paths:
- config-repo
username: 13113691357
password: 15671628341qwe
label: master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.启动类
@EnableConfigServer
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4.隐射关系
URL 与配置文件的映射关系如下:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
上面的 url 会映射{application}-{profile}.properties
对应的配置文件,{label}
对应 git 上不同的分支,默认为 master。
#访问下面链接,可以看到git中的配置信息
http://localhost:7001/didispace/prod/config-label-test
1
2
2
# 5.应用服务配置
bootstrap.properties,不需要 application.yaml
spring.application.name=didispace
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:7001/
server.port=7002
1
2
3
4
5
2
3
4
5
# 6.应用服务门户
@RefreshScope
@RestController
class ConfigController {
@Value("${from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 七.zuul
# 1.pom 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.配置文件
网关配置方式有多种,默认、URL、服务名称、排除|忽略、前缀。
#端口号
server:
port: 8888
spring:
application:
name: zuul-service #服务名称
#路由规则:
zuul:
sensitiveHeaders: Cookie,Set-Cookie,Authorization
routes:
portal:
path: /portal-service/** #访问路径:http:/localhost:8888/portal-service/portal/1
service-id: portal-service
goods:
path: /goods-service/** #http:/localhost:8888/goods-service/kwanGoodsInfo/1
service-id: goods-service
host:
connect-timeout-millis: 5000 #超时时间
prefix: /api #访问路径:http:/localhost:8888/api/portal-service/portal/1 http:/localhost:8888/api/goods-service/kwanGoodsInfo/1
retryable: true
ignored-services: portal-service #感略某个服务名,禁止通过该服务名访可
# ignored-services: * #禁止通过所有的服务名访间
ignored-patterns: /**/feign/** #不给匹配此棋式的路径进行路由·那么你到时候访间不到
LogFilter:
route:
disable: true #用LogFilter过滤器
# semaphore:
# max-semaphores: 100
# ribbon-isolation-strategy: thread
# strip-prefix: false
#服务提供者
eureka:
client:
service-url:
defaultZone: http://eureka8767:8767/eureka/,http://eureka8768:8768/eureka/,http://eureka8769:8769/eureka/
ribbon:
ConnectTimeout: 250 #连接超时时间(ms),默认值为250ms
ReadTimeout: 2000 #通信超时时间(ms),默认值为2000ms
MaxAutoRetriesNextServer: 0 #对同一服务不同实例重试次数(同一服务下集群个数的重试次数)
MaxAutoRetries: 2 #对同一实例重试的次数(单个集群节点服务重试的次数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 3.启动类
@EnableZuulProxy
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 4.访问地址
#通过zuul访问服务的,URL地址默认格式为:
http://zuulHostIp:port/要访问的服务名称/服务中的URL
1
2
2
# 八.consul
# 1.安装
#安装地址
https://developer.hashicorp.com/consul/downloads
#执行
brew tap hashicorp/tap
brew install hashicorp/tap/consul
#启动
consul agent -dev
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2.控制台
#访问地址
http://127.0.0.1:8500/ui/dc1/services
1
2
2
# 3.配置信息
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
1
2
3
4
2
3
4
#端口号
server:
port: 8500
spring:
application:
name: consul-service #服务名称
cloud:
consul:
host: localhost
port: 8500
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
public class ConsulApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulApplication.class, args);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("/consul")
public class ConsulController {
@GetMapping(value = "/test", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
public Result test() {
return Result.ok("consul 访问成功");
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9