三年前搭建Springcloud框架的记录,如有错漏欢迎指正。
版本信息 :
Spring boot :2.0.1.RELEASE
Spring cloud : Finchley.RELEASE(springcloud版本不同,则后续所有组件依赖皆有不同)
Jdk :1.8
Maven :3.2
一、 Eureka服务(Eureka-Server模块)
1、 Eureka(服务注册与发现)需添加eureka server 依赖。
2、 需在启动类添加 @EnableEurekaServer 注解。
3、 需在application添加如下配置:
server:
port: 8081
eureka:
instance:
hostname: yangww-Eureka-Server
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4、 然后启动项目访问localhost:8088,看到Eureka服务界面,Eureka注册中心就已经启动成功。
注意:需注意spring boot与spring cloud 版本问题,版本冲突,则容易编译错误。
二、 Eureka生产者(Eureka-Client模块)
1、Eureka生产者需添加eureka server 依赖。
2、需在启动类添加 @ EnableEurekaClient注解(非必须)。
3、需在application添加如下配置:
server:
port: 8082
spring:
application:
name: Eureka-Client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/
4、 然后启动项目访问localhost:8081,看到Eureka服务界面多了一个Eureka-Client服务。
三、 Ribbon消费者(Ribbon-Client模块)
1、 以ribbon作为跨服务调用的消费者,需添加 ribbon、eureka discovery、eureka server依赖。
2、 需在application添加如下配置:
server:
port: 8082
spring:
application:
name: Eureka-Client1
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/
全局ribbon超时配置
ribbon:
OkToRetryOnAllOperations: false #对所有操作请求都进行重试,默认false
ReadTimeout: 10000 #负载均衡超时时间,默认值5000
ConnectTimeout: 2000 #ribbon请求连接的超时时间,默认值2000
MaxAutoRetries: 0 #对当前实例的重试次数,默认0
MaxAutoRetriesNextServer: 1 #对切换实例的重试次数,默认1
3、 在启动类开启负载均衡,如下:
@SpringBootApplication
public class EurekaRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate()
{
return new RestTemplate();
}
}
4、 创建服务类,如下:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name)
{
return restTemplate.getForObject("http://Eureka-Client1/hi?name=" + name, String.class);
}
}
四、 Feign消费者(Feign-Client模块)
Feign的服务生产者与常规服务一样,只是服务调用者需要配置。
1、 以feign作为跨服务调用的消费者,需添加 feign、eureka discovery、eureka server依赖。
2、 需在application添加如下配置:
server:
port: 8085
spring:
application:
name: Feign-Client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/
feignName:
feignClient:
name: Feign-Client
feignServer:
name: Feign-Server
#hystrix断路器超时设置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
全局ribbon超时配置
ribbon:
OkToRetryOnAllOperations: false #对所有操作请求都进行重试,默认false
ReadTimeout: 10000 #负载均衡超时时间,默认值5000
ConnectTimeout: 2000 #ribbon请求连接的超时时间,默认值2000
MaxAutoRetries: 0 #对当前实例的重试次数,默认0
MaxAutoRetriesNextServer: 1 #对切换实例的重试次数,默认1
3、 在启动类上加@EnableDiscoveryClient、@EnableFeignClients 注解(非必须)。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientApplication.class, args);
}
}
4、 定义接口,如下:
@FeignClient(value = "${feignName.feignServer.name}")
public interface FeignClientService {
@RequestMapping("/feignServer/test")
String test();
}
五、 Hystrix断路器
1、 添加hystrix依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、 启动类加@EnableHystrix注解开启Hystrix
3、 在需熔断的方法上加@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,如下(熔断方法参数需与调用方法参数相同):
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
public String hiError(String name) {
return "hi,"+name+",sorry,error!";
}
}
Feign自带断路器,只需如下操作:
1、 在配置文件中设置 feign.hystrix.enabled=true
2、 在feignClient接口【FeignClientService.class】的注解中添加fallback的指定类,如:
@FeignClient(value = "${feignName.feignServer.name}" , fallback = HystrixServiceImpl.class)
public interface FeignClientService {
@RequestMapping("/feignServer/test")
String test();
}
3、 断路器实现类需实现FeignClientService接口,并注入到IOC,如下:
@Component
public class HystrixServiceImpl implements FeignClientService{
@Override
public String test() {
return "断路器test";
}
}
(Hystrix仪表盘
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
2、 在主程序启动类中加入@EnableHystrixDashboard注解,开启hystrixDashboard
3、 打开浏览器:访问http://localhost:8085/hystrix
4、 点击monitor stream,进入下一个界面,访问:http://localhost:8085/feignClient/test,此时会出现监控界面
六、 Zuul路由网关
Zuul配置
1、 添加依赖:
<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>
2、在其入口applicaton类加上注解@EnableZuulProxy,开启zuul的功能。
3、需在application添加如下配置:
server:
port: 8086
spring:
application:
name: Zuul-Server
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8081/eureka/
zuul:
routes:
api-a:
path: /api-a
5、 然后启动项目访问http://localhost:8086/api-b/ribbonClient/test,看到跳转到Ribbon-Client服务。
Zuul + Hystrix断路器
1、 添加断路器依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、 启动类添加@EnableHystrix注解
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
@EnableHystrix
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
3、 创建断路器实现类
package com.zuul.service;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
@Component
public class ZuulHystrixServiceImpl implements FallbackProvider{
@Override
public String getRoute() {
RequestContext re = RequestContext.getCurrentContext();
return "Ribbon-Server";
}
@Override
public ClientHttpResponse fallbackResponse(String s, Throwable throwable) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return this.getStatusCode().value();
}
@Override
public String getStatusText() throws IOException {
return this.getStatusCode().getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("Service-user不可用".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
headers.setContentType(mt);
return headers;
}
};
}
}
Zuul + Filter过滤器
1、 创建过滤器实现类
package com.zuul.service;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class ZuulFilterServiceImpl extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(ZuulFilterServiceImpl.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("token");
if(accessToken == null) {
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
}catch (Exception e){}
return null;
}
log.info("ok");
return null;
}
}
源代码地址
https://download.csdn.net/download/yangchenbeiluo/12046296
Original: https://blog.csdn.net/yangchenbeiluo/article/details/127001720
Author: yangchenbeiluo
Title: Springcloud使用记录