# springcloud-microservices-examples **Repository Path**: ChuYunOS/springcloud-microservices-examples ## Basic Information - **Project Name**: springcloud-microservices-examples - **Description**: # spring cloud netflix 微服务使用实例 为想使用微服务,却不知从何入手的同学,提供参考 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 27 - **Created**: 2017-12-16 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # spring cloud 微服务架构实例 ``` mvn clean package 即可编译整个项目 ``` **项目介绍&功能说明** 1. eureka-server服务注册与发现 2. gateway zuul网关 3. monitor-dashboard 服务调用监控看板 4. web-console WEB管理控制台 5. uaa-service 用户中心 其他: 日志使用ELK进行采集存储检索,消息中间件使用RabbitMQ **运行方式** 首先要启动项目所依赖的中间件 ELK、rabbitMQ 1. java -jar eureka-server\target\eureka-server-1.0.0.jar 2. java -jar gateway\target\gateway-1.0.0.jar 3. java -jar monitor-dashboard\target\monitor-dashboard-1.0.0.jar 4. java -jar web-console\target\web-console-1.0.0.jar 5. java -jar uaa-service\target\uaa-service-1.0.0.jar **视频演示** TODO **参考我在解决如下问题的思路,这里只是简单的介绍,更多的内容靠源码表达了**。有时间再单独就微服务的每一块写博客。 ## eureka 服务注册与发现 1、怎么样实现eureka自身的高可用? 方法是通过利用eureka的特性(eureka本身就是一个微服务),配置多个eureka实例间相互依赖。 且当微服务在其中一个实例注册后,会自动同步到eureka集群中。 配置示例: ``` eureka: client: registerWithEureka: true fetchRegistry: false serviceUrl: defaultZone: http://peer1:8761/eureka/,http://peer2:8761/eureka/ ``` 2、netty如何与springCloud集成? 参考netty-service的实现 核心代码段: **.web(false)** ``` @SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker @ComponentScan("com.zf.spring") public class TheserviceApplication { public static void main(String[] args) { new SpringApplicationBuilder(TheserviceApplication.class).web(false) .run(args); } } ``` **implements ApplicationContextAware** ``` @Service public class NettyRunner implements ApplicationContextAware { ``` ## zuul API网关 1、如果实现权限校验? 一种简单的方式JWT[(Json Web Token) ](https://tools.ietf.org/html/rfc7519 "RFC 7519 ") 使用jwt实现令牌的发放及校验,令牌(Token)本身包含了一系列声明,应用程序可以根据这些声明限制用户对资源的访问; 2、如何实现微服务与普通url混合使用? 参考[spring cloud ](http://projects.spring.io/spring-cloud/spring-cloud.html#_router_and_filter_zuul "Spring-cloud ") 文档 3、如何实现多个api聚合? 本实例中采取定制的route的方式:merge-one,这个路由是为聚合服务定制的。 它会解析来自前端特定的请求参数,如下: ``` { "start":"theserivce,oschina", "steps":[ { "name":"oschina", "fullPath":"/oschina/event/2231301", "method":"post", "data":"xxx" }, { "name":"theserivce", "fullPath":"/test-service/users/listUser", "method":"post", "data":"yyy" } ] } ``` 对fullPath利用zuul内部API进行路由二次匹配,找到对应的微服务或者http url。 聚合服务意味着有多个API需要调用,在这个实例中,使用RxJava实现了API的并发调用,显著提高响应速度。 RxJava实现的并发Http请求,关键代码如下(非源码,仅作为思路参考): ``` final java.util.concurrent.atomic.AtomicBoolean atomicBoolean = new AtomicBoolean( true); ArrayList> iterables = new ArrayList>(); for (int i = 0; i < 100; i++) { final int x = i; Observable subscribeOn = Observable.create( new Observable.OnSubscribe() { @Override public void call(Subscriber t) { System.out.println(">>>>>>>x" + x); try { Thread.sleep(500L); // 根据地址获取请求 HttpGet request = new HttpGet( "http://www.baidu.com/" + x);// 这里发送get请求 // 获取当前客户端对象 HttpClient httpClient = HttpClientBuilder .create().build(); // 通过请求对象获取响应对象 HttpResponse response = httpClient .execute(request); // 判断网络连接状态码是否正常(0--200都数正常) if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { System.err.println(Thread.currentThread() .getName() + " >>> "); String string = EntityUtils.toString(response.getEntity(), "utf-8"); t.onNext("oschina" + x + "_" + string.length()); t.onCompleted(); } } catch (Exception e) { e.printStackTrace(); } } }).subscribeOn(Schedulers.io()); iterables.add(subscribeOn); } Observable zip = Observable.zip(iterables, new FuncN() { @Override public String call(Object... obj) { StringBuffer stringBuffer = new StringBuffer(); for (Object o : obj) { stringBuffer.append(o); } return stringBuffer.toString(); } }); final long i = System.currentTimeMillis(); zip.subscribe(new Observer() { @Override public void onCompleted() { atomicBoolean.set(false); System.err.println("onCompleted"); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(String t) { System.err.println(Thread.currentThread().getName() + " >>> "); System.err.println(System.currentTimeMillis() - i); System.err.println(t); } }); while (atomicBoolean.get()) { } System.out.println("the end"); ``` ## Hystrix 1、如何实现微服务的熔断机制? 2、怎样给接口返回设置统一的错误信息? ## Turbine 1、系统流量如何做到实时监控? 本处仅对gateway做流量监控,使用方式: ``` 启动eureka、gateway、the-service、monitor-dashboard 访问http://localhost:8989/ 输入http://localhost:8989/turbine.stream 点击Monitor Stream 就可以已经看到有服务显示在看板了, 访问:http://localhost:8765/the-service/users/listUser 即可在看板中看到the-service这个服务发生了波动。 ``` 使用Hystrix Dashboard作为监控看板,turbine作为多服务聚合监控。 参考[spring cloud ](http://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_dashboard "Spring-cloud ") 文档 关键代码段: **@EnableCircuitBreaker** ``` @SpringBootApplication @EnableZuulProxy @EnableCircuitBreaker @ComponentScan("com.zf.spring") @EnableConfigurationProperties public class GatewayApplication { public static void main(String[] args) { new SpringApplicationBuilder(GatewayApplication.class).web(true).run(args); } } ``` ## WEB管理控制台 1、微服务之如何人工管理? 使用方式:启动web-console,访问http://localost:8081即可, 目前是集成spring-boot-admin,后续打算拓展一些功能进去。 ## UAA账户及认证 参考jhipster、CloudFoundry中UAA的实现方式。我的[实现思路 ](# "实现思路 "): 1、网关配置uaa-token这个入口为免校验 2、调用方通过/uaa-service/token/by**获取token,token中包含scope(允许访问的路径) 3、服务调用时,带上token参数或者将token存在头部Authorization里面。 4、网关通过访问路径与token中合规路径进行匹配,通过则放行。