# spring-cloud-2.x
**Repository Path**: liujunlin/spring-cloud-2.x
## Basic Information
- **Project Name**: spring-cloud-2.x
- **Description**: No description available
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2018-02-01
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# spring-cloud-2.X
本项目环境:
spring-cloud Finchley.RC1
spring boot 2.0.1.RELEASE
JDK1.8
  hosts配置
  
    #注册中心
    127.0.0.1 regserver1
    127.0.0.1 regserver2
    127.0.0.1 regserver3
	
请按如下顺序搭建、启动应用:
#1.高可用注册中心
注册中心选用eureka,当然你也可以选用zookeeper。
区别可参考[https://www.cnblogs.com/jieqing/p/8394001.html](https://www.cnblogs.com/jieqing/p/8394001.html "ZooKeeper、Eureka对比")
##application.yml
	sec:
	  user:
	    name: admin
		#使用org.springframework.security.crypto.scrypt.SCryptPasswordEncoder加密
	    password: $e0801$AvWVxfGeD4EkdvK08Z8EMkYmlhVKsTZBXyC1l7SztdU8OPnEXrIbBdRsTO+wAPvQkIubRUY3wLoOdJd0+rFWog==$0LPuxlB83BE26qaODEwN7Tnhqn8GUKkgr/NYPNlQeXs=
	    role: USER
三个注册中心的配置application-server1.yml、application-server2.yml、application-server2.yml
##bootstrap.yml
	
	#注册中心应用名称,三个节点必须统一
	spring:
	  application:
	    name: eureka-server
#2.配置中心
用于统一配置文件,尽量避免去各个应用进行分散配置。方便管理。
##application.yml
	server:
	  port: 3001
	spring:
	  profiles:
		#使用本地目录
	    active: native
	  application:
		#注册中心应用名称
	    name: XDH-CONFIG-SERVER
	  cloud:
	    config:
	      server:
	        native:
			  #配置文件的存放地址,这里用的本地目录,也可以配置成从git、svn读取
	          search-locations: file:///E:/Project/spring-cloud-2.x/config-repo
	eureka:
	  instance:
	    prefer-ip-address: true
	  client:
	    service-url:
		  #将注册中心注册到注册中心,这样可以启动多个配置中心提供高可用服务
	      defaultZone: http://admin:ABCabc123@regserver1:8001/eureka/,http://admin:ABCabc123@regserver2:8002/eureka/,http://admin:ABCabc123@regserver3:8003/eureka/
	
##bootstrap.yml
	#为了安全性,可以使用证书加密配置内容,对于安全性要求较高的配置,可以进行加密存放。jks证书使用keytool生成
	encrypt:
	  key-store:
	    location: classpath:/xdh-cloud-key.jks
	    alias: xdh-cloud-key
	    password: ABCabc123
#3.安全签名颁发服务 jwt-security-provider
用于提供jwt token的生成服务,前端应用登陆成功获取该token后则可以调用各个服务。为了安全,采用https连接,为了方便,采用配置中心相同的证书。
#######        由于自签证书默认是不被浏览器信任,因此第一次访问https链接时会询问是否信任,所以需要用页面去访问登陆接口,并继续完成https请求,后续才可以用ajax去调用https验证接口
##bootstrap.yml
	spring:
	  application:
	    name: jwtsecurity-provider
	  cloud:
	    config:
	      profile: ${spring.profiles.active}
	      name: ${spring.application.name}
		  #从注册中心获取配置中心的配置
	      discovery:
	        enabled: true
	        service-id: XDH-CONFIG-SERVER
	eureka:
	  client:
	    service-url:
	      defaultZone: http://admin:ABCabc123@regserver1:8001/eureka,http://admin:ABCabc123@regserver2:8002/eureka,http://admin:ABCabc123@regserver3:8003/eureka
##application.yml
	server:
	  port: ${jwtsecurity.provider.port}
	  #如果使用https,则配置此项
	  ssl:
	    key-store: cloud-config/src/main/resources/xdh-cloud-key.jks
	    key-store-password: ABCabc123
	    key-store-type: JKS
	    keyAlias: xdh-cloud-key
##jwtsecurity-provider-dev.yml
	security:
	  jwt:
	    #签名有效期
	    tokenExpirationSeconds: 600
	    #下次刷新时间,供前端获取后,设置一个刷新token的延迟时间
	    tokenNextRefreshSeconds: 500
#4.安全签名检验过滤模块 jwt-security-client-filter
该模块需要集成到需要安全检验的消费者中。
用于提供jwt token的检验服务,若token无效或失效,直接返回失败json消息,不再调用后端服务。
#5.producer-*-api
生产者与消费者共同的API,消费者根据API调用相应的服务。
#6.生产者producer
提供rest服务,实现了相应的API接口。服务会注册到注册中心供调用。
#7.消费者consumer
一般而言,消费者定义会为与前端交互的应用,可能会调用部分服务提供者。
#8.日志收集zipkin
用于展示各服务之间的调用情况,包括各环节调用时长、依赖链分析,方便捕捉异常的应用。
###部署步骤
###8.1 部署zipkin server
[https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec](https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec "下载最新版本")
下载zipkin-server-*-exec.jar,直接java -jar启动,默认访问地址http://localhost:9411/
###8.2 集成zipkin客户端(HTTP)
在需要zipkin进行分析应用中,引入 
	
        org.springframework.cloud
        spring-cloud-starter-zipkin
    
配置文件中
	spring:
	  zipkin:
	    base-url: http://localhost:9411
为了简化,只需在API模块中引入spring-cloud-starter-zipkin,在配置中心application.xml引入地址base-url配置
###8.3 集成zipkin客户端(MQ)
基于HTTP方式的日志采集会有性能损耗,通常会使用MQ来作为日志采集通道,性能较好。
	 
		
	        
	        
        
        
            org.springframework.cloud
            spring-cloud-starter-zipkin
        
        
            org.springframework.amqp
            spring-rabbit
        
然后配置MQ地址:
	spring:
	  rabbitmq:
	      host: localhost
	      port: 5672
	      username: admin
	      password: ABCabc123
注意:部分资料说的是引入spring-cloud-sleuth-stream依赖,实际该依赖在新版本中已被标志为过时。
#9.前端开发基础库及规范 web-static
使用require
引用authService用于权限检验。在页面页面跳转前调用doAuth,如权限检查不通过,则跳转到登陆页面。
##nginx.conf配置
	server {
		listen       9991;
		location / {
			autoindex on;
			autoindex_exact_size on;
			autoindex_localtime on;
			root   E:/Project/spring-cloud-2.x/web-static;
		}
	}
## config/authConfig.js
	define(function () {
	    return {
			//登陆页面地址
	        LOGIN_PAGE_URL:"http://localhost:9991/test/auth/login.html",
			//登陆接口地址
	        JWT_LOGIN_URL:"https://localhost:8888/auth/login",
			//刷新token接口地址
	        REFRESH_TOKEN_URL:"https://localhost:8888/auth/refreshToken"
	    };
	});
#10.Spring Cloud Gateway 服务网关
基于Spring的微服务结点在能力上没有高低贵贱之分,但是在角色上会分为边缘服务和内部服务两部分。内部服务顾名思义是为对内暴露服务的结点,供架构内部来调用;边缘服务是对外部网络暴露的服务结点,也就是对外API接口。
###10.1 网关路由配置
	zuul:  
	  routes:  
	    demo-feign-freeservice:  
	      path: /api-service/**  
	    user-service:  
	      path: /api-consumer/**  
	      serviceId: demo-feign-freeconsumer  
	    163:  
	      path: /163  
	      url: http://www.163.com/  
这里对路由的配置用了3种格式,体现了API Gateway的路由分发功能:
第一种格式(path-url):如果请求/163这个地址,将会转发到http://www.163.com上去
第二种(path-serviceId):如果请求/api-consumer开头的地址,将会转发到eureka上serviceId为“demo-feign-freeconsumer”这个服务上去。
第三种(给微服务名指定path):给demo-feign-freeservice这个微服务指定了它的请求地址是/api-service/**
(其实这里还隐藏了第四种:什么都不配,默认给注册到eureka上的所有服务以第三种方式进行路由,path就是微服务自己的名字,但是此种方式又是不安全的,相当于将非边缘服务也暴露给外网,一般需要关闭这个默认配置zuul.ignored-services=*,或者至少将受保护的微服务列表维护到zuul.ignored-services中)
###10.2 路由匹配规则:
/user-service/? 很少用,支持/user-service/后拼接任意一个字符,例如/user-service/a、/user-service/1,不支持/user-service/123
/user-service/* 较少用,支持/user-service/后拼接任意一个字符例如/user-service/abc、/user-service/1,不支持多级目录/user-service/abc/b
/user-service/** 通用,只要以/user-service/开头就可以,后面路径没要求。
如果路由规则有交集的部分,只能使用YAML文件来做application的配置文件,不能使用properties,因为YAML是有序的(流解析),properties无序的(HashMap)。
例如:
	zuul:  
	  routes:  
	    user-service-ext:  
	      path: /user-service/ext/**  
	      serviceId: user-service-ext  
	    user-service:  
	      path: /user-service/**  
	      serviceId: user-service
###10.3 网关过滤器
	public class AccessFilter extends ZuulFilter{	
		@Override
		public Object run() {
			RequestContext ctx = RequestContext.getCurrentContext();
			HttpServletRequest request = ctx.getRequest();
			
			Object accessToken = request.getParameter("accessToken");
			if(accessToken==null) {
				ctx.setSendZuulResponse(false);
				ctx.setResponseStatusCode(401);
				//为了被error过滤器捕获
				ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				ctx.set("error.exception",new RuntimeException("AccessToken is null"));
				return null;
			}
			return null;
		}
	
		@Override
		public boolean shouldFilter() {
			RequestContext ctx = RequestContext.getCurrentContext();
			HttpServletRequest request = ctx.getRequest();
			if(request.getRequestURI().equals("/163")) {
				return false;
			}else {
				return true;
			}		
		}
	
		@Override
		public int filterOrder() {
			return 0;
		}
	
		@Override
		public String filterType() {
			return "pre";
		}
	
	}
继承抽象类zuulFilter,有4个方法需要实现:
filterType:过滤器类型,决定了过滤器在哪个周期生效。类型有pre、route、post、error,对应Spring AOP里的前加强、前后加强、后加强、异常处理。
filterOrder:过滤器的执行顺序,多个过滤器同时存在时根据这个order来决定先后顺序,越小优先级越高
shouldFilter:过滤器是否被执行,只有true时才会执行run()里的代码。我们这里除开访问163会放行其他情况都需要进行过滤判断,在生产环境一般是要根据函数条件来判断的。
run:过滤逻辑。
整个代码的zuul的代码逻辑很简单,对外统一的访问路径是zuul服务的地址,如果直接访问163过滤器不生效直接放行,访问其它内部服务结点需要判断是否有accessToken。
#10.spring-cloud-bus 消息总线
用于监听配置的更新。
步骤一:
需要动态更新的应用,加入依赖
    
        org.springframework.cloud
        spring-cloud-starter-bus-amqp
    
步骤二:
在需要更新配置的类上加@RefreshScope注解 
步骤三:为了方便管理,在配置中心上开启刷新功能(Spring Boot 2不再默认开放节点,需要自行配置)
    management:
      endpoints:
        web:
          exposure:
            include: "bus-refresh"
刷新操作:http://localhost:3001/actuator/bus-refresh
#11.ELK日志存储
#12.Hystrix 断路器
引入
	
        org.springframework.cloud
        spring-cloud-starter-netflix-hystrix
    
在需要断路器的方法上,增加注解
	@HystrixCommand(fallbackMethod = "addServiceFallback")
    public Object queryPostgresql(String sql) {
        return postgresqlService.queryForList(sql);
    }
    public String addServiceFallback(String sql) {
        return "sql could not excute";
    }
注意:addServiceFallback 方法的参数必须与queryPostgresql上的相同,网上一些资料可能没提到。否则,可能会出现异常:
com.netflix.hystrix.contrib.javanica.exception.FallbackDefinitionException:
fallback method wasn't found: defaultUser([class java.lang.Long])
#Spring Cloud 学习参考
[http://blog.didispace.com](http://blog.didispace.com "程序猿DD")
[https://github.com/yinjihuan/spring-cloud](https://github.com/yinjihuan/spring-cloud "微服务研究案列")
[https://www.cnblogs.com/shunyang](https://www.cnblogs.com/shunyang "静静的码农")
[https://my.oschina.net/ityouknow/blog/1923560](https://my.oschina.net/ityouknow/blog/1923560 "Spring Cloud 开源软件都有哪些")