# user-guide-springcloud **Repository Path**: lurker8/user-guide-springcloud ## Basic Information - **Project Name**: user-guide-springcloud - **Description**: spring_cloud例子 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2017-06-19 - **Last Updated**: 2024-07-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # [云框架]基于Spring Cloud的微服务架构 v1.5 ![](https://img.shields.io/badge/Release-v1.5-green.svg) [![](https://img.shields.io/badge/Producer-elvis2002-orange.svg)](CONTRIBUTORS.md) ![](https://img.shields.io/badge/License-Apache_2.0-blue.svg) [微服务](https://martinfowler.com/articles/microservices.html)与传统架构模式相比,具有语言无关性、独立进程通讯、高度解耦、任务边界固定、按需扩展等特点,非常适合互联网公司快速交付、响应变化、不断试错的需求,也因此受到了像Twitter、Netflix、Amazon、eBay这样的科技巨头的青睐。 目前主流微服务框架包括Spring Cloud、Dubbo、API Gateway等,其中[Spring Cloud](http://projects.spring.io/spring-cloud/)是一套快速构建分布式系统中常见工具的集合,利用Spring Boot的开发便利性,Spring Cloud为JVM云应用开发中的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的实现方式。 相比Dubbo等RPC框架,Spring Cloud是一个比较新的微服务架构基础框架选择,2016年才推出的1.0 release版本,不过Spring Cloud的方案完整度非常高,各个子项目几乎覆盖了微服务架构的方方面面。从目前的关注度和活跃度来看,Spring Cloud很可能会成为微服务架构的标准。([Spring Cloud技术分析](http://tech.lede.com/2017/03/15/rd/server/SpringCloud0/)) 本篇[云框架](ABOUT.md)总结过去数十个微服务架构项目的成功经验,并结合典型案例[PiggyMetrics](https://github.com/cloudframeworks-springcloud/PiggyMetrics)(一款个人财务管理应用),为开发者提供基于Spring Cloud的微服务架构落地最佳实践。 * 初学者可通过实例代码、文档快速学习Spring Cloud及微服务,并在社群中交流讨论 * 已有一定了解的开发者,不必从零开始开发,仅需在云框架基础上替换部分业务代码,即可将最佳实践应用于生产环境并立即产生价值 相关云框架:[[云框架]KONG API Gateway](https://github.com/cloudframeworks-apigateway/user-guide-apigateway) # 内容概览 * [快速部署](#快速部署) * [框架说明-业务](#框架说明-业务) * [框架说明-组件](#框架说明-组件) * [组件架构](#组件架构) * [配置Spring Cloud Config](#Spring-Cloud-Config) * [配置Netflix Eureka](#Netflix-Eureka) * [配置Netflix Zuul](#Netflix-Zuul) * [配置Netflix Ribbon](#Netflix-Ribbon) * [配置Netflix Hystrix](#Netflix-Hystrix) * [配置Netflix Feign](#Netflix-Feign) * [如何变成自己的项目](#如何变成自己的项目) * [生产环境](#生产环境) * [常见问题](#常见问题) * [更新计划](#更新计划) * [社群贡献](#社群贡献) # 快速部署 1. [准备Docker环境](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/install%20docker.md) 2. 克隆完整代码 ``` git clone https://github.com/cloudframeworks-springcloud/PiggyMetrics ``` 3. 设置环境变量 ``` export CONFIG_SERVICE_PASSWORD=root export NOTIFICATION_SERVICE_PASSWORD=root export STATISTICS_SERVICE_PASSWORD=root export ACCOUNT_SERVICE_PASSWORD=root export MONGODB_PASSWORD=root ## 必填,其他变量可不设置 ``` 4. 使用[docker-compose](https://docs.docker.com/compose/install/)运行如下命令([docker-compose.yml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/docker-compose.yml))(或查看[通过脚本分别部署每个组件](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/deploy%20via%20script.md)) ``` docker-compose -f docker-compose.yml up -d ``` 5. 访问路径 http://DOCKER-HOST:80 - Gateway http://DOCKER-HOST:8761 - Eureka Dashboard http://DOCKER-HOST:9000/hystrix - Hystrix Dashboard http://DOCKER-HOST:8989 - Turbine stream (source for the Hystrix Dashboard) http://DOCKER-HOST:15672 - RabbitMq management (默认账号guest/默认密码guest) # 框架说明-业务 Piggymetrics通过Spring Cloud实现微服务架构,应用被分解为**账户服务**([ACCOUNT SERVICE](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/account-service))、**统计服务**([STATISTICS SERVICE](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/statistics-service))、**通知服务**([NOTIFICATION SERVICE](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/notification-service))等三个核心微服务。每个微服务都是围绕业务能力组织的可独立部署的应用程序,拥有独立的数据库并使用同步的[REST API](http://www.restapitutorial.com/)实现微服务与微服务之间的通信。 PiggyMetrics业务架构如下图所示:
账户服务模块包含一般用户输入逻辑和验证:收入/费用项目,储蓄和帐户设置。 方法 | 路径 | 描述 | 用户验证 | UI可用 ------------- | ------------------------- | ------------- |:-------------:|:----------------:| GET | /accounts/{account} | 获取特定账户数据 | | GET | /accounts/current | 获取当前账户数据 | × | × GET | /accounts/demo | 获取demo账户数据 (预填充收入/支出项目等) |   | × PUT | /accounts/current | 保存当前账户数据 | × | × POST | /accounts/ | 注册新账户 |   | × 统计服务模块执行主要统计参数的计算,并捕获每个帐户的时间序列。 方法 | 路径 | 描述 | 用户验证 | UI可用 ------------- | ------------------------- | ------------- |:-------------:|:----------------:| GET | /statistics/{account} | 获取特定账户统计         | | GET | /statistics/current | 获取当前账户统计 | × | × GET | /statistics/demo | 获取demo账户统计 |   | × PUT | /statistics/{account} | 创建或更新时间系列数据点指定的帐户 | | 通知服务模块存储用户联系信息和通知设置(如提醒和备份频率),计划工作人员从其他服务收集所需的信息,并向订阅的客户发送电子邮件。 方法 | 路径 | 描述 | 用户验证 | UI可用 ------------- | ------------------------- | ------------- |:-------------:|:----------------:| GET | /notifications/settings/current | 获取当前账户通知设置 | × | × PUT | /notifications/settings/current | 保存当前账户通知设置 | × | × # 框架说明-组件 Piggymetrics基础服务设施中用到了Spring Cloud Config、Netflix Eureka、Netflix Hystrix、Netflix Zuul、Netflix Ribbon、Netflix Feign等组件,而这也正是Spring Cloud分布式开发中最核心的组件。 组件架构如下图所示:
* 账户服务通过远程客户端(Feign)调用统计服务及通知服务,通过Ribbon实现负载均衡,并在调用过程中增加了断路器(Hystrix)的功能; * 由于服务发现后才能调用,因此账户服务、统计服务、通知服务通过注册中心(Eureka)实现互相发现; * API Gateway(Zuul)提供对外统一的服务网关,首先从注册中心(Eureka)处获取相应服务,再根据服务调用各个服务的真实业务逻辑; * 服务调用过程通过聚合器(Turbine)统一所有断路信息; * 整个业务过程中所有服务的配置文件通过Spring Cloud Config来管理,即起什么端口、配置什么参数等; * 认证机制通过Auth service实现,提供基本认证服务; * Spring Cloud Config、Eureka、Ribbon、Hystrix、Feign以及Turbine均为标准组件,与业务之间没有强关系,不涉及到业务代码,仅需简单配置即可工作。 ## 配置Spring Cloud Config 在PiggyMetrics项目中,[config_server](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/config)从本地类路径加载配置文件:
我们可以在[config service](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/config/src/main/resources/shared)中查看shard目录资源,其中`application.yml`被所有客户端应用共享,比如当Notification-service请求配置时,使用`shared/notification-service.yml`和`shared/application.yml`配置服务响应。 使用Spring Cloud config需要在[pom.xml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/config/pom.xml)中添加spring-cloud-starter-config(它将从配置中心自动获取配置),并在各服务资源目录bootstrap.yml中,例如[moinitoring的bootstrap.yml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/monitoring/src/main/resources/bootstrap.yml)中添加如下代码: ``` spring: application: name: 服务名 cloud: config: uri: http://config:8888 fail-fast: true ``` 配置文件修改后可通过 http://DOCKER-HOST:DOCKER-PORT/xxx/refresh 刷新配置(xxx表示服务根路径),无需重启服务。 **[进一步了解Spring Cloud Config](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/spring%20cloud%20config%20basic.md)** ## 配置Netflix Eureka PiggyMetrics通过Eureka server实现[registy](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/registry), 代码逻辑比较简单和标准,不用做任何修改,需要注意的是在[bootstrap.yml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/registry/src/main/resources/bootstrap.yml)加入配置中心服务地址信息。 ``` spring: cloud: config: uri: http://config:8888 fail-fast: true password: ${CONFIG_SERVICE_PASSWORD} username: user ``` **[进一步了解Netflix Eureka](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/netflix%20eureka%20basic.md)** ## 配置Netflix Zuul PiggyMetrics借助Netflix Zuul实现[gateway](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/gateway),代理授权服务、账户服务、统计服务和通知服务,这里的代码比较简单,基本上是标准的,不需要修改。 我们在实际业务的开发中,在[GatewayApplication.java](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/gateway/src/main/java/com/piggymetrics/gateway/GatewayApplication.java)用具体业务替换相应的服务即可。 ``` @EnableZuulProxy ## 增加zuul proxy代理功能 public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } } ``` 在resources目录下增加[static](https://github.com/cloudframeworks-springcloud/PiggyMetrics/tree/master/gateway/src/main/resources/static)录存放你的静态资源(如html、css、images等) 在zuul的配置文件[gateway.yml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/config/src/main/resources/shared/gateway.yml)中增加代理服务的配置 ``` zuul: ignoredServices: '*' host: connect-timeout-millis: 20000 ## 超时时间 ocket-timeout-millis: 20000 routes: auth-service: ## 认证服务 path: /uaa/** ## 匹配路径 url: http://auth-service:5000 ## 服务路径(http方式) stripPrefix: false ## 是否包括前缀 sensitiveHeaders: account-service: path: /accounts/** serviceId: account-service ## 通过服务ID动态查找 stripPrefix: false sensitiveHeaders: statistics-service: path: /statistics/** serviceId: statistics-service stripPrefix: false sensitiveHeaders: notification-service: path: /notifications/** serviceId: notification-service stripPrefix: false sensitiveHeaders: ``` **[进一步了解Netflix Zuul](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/netflix%20zuul%20basic.md)** ## 配置Netflix Ribbon PiggyMetrics并没有显式的去定义Netflix Ribbon的使用,但是在Zuul、Feign等组件中隐式的使用到了Ribbon,我们在实际的业务开发中,也不需要刻意定义Ribbon。 **[进一步了解Netflix Ribbon](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/netflix%20ribbon%20basic.md)** ## 配置Netflix Hystrix 项目中统一定义了熔断策略(不涉及代码侵入): ``` hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 10000 ## 10000ms 超时限制 ``` 由于Hystrix的监控只针对单个节点,因此PiggyMetrics通过**Netflix Turbine**来监控集群下Hystrix的metrics情况。 实现客户端将Hystrix命令推送到Turbine,只需要在客户端添加如下代码即可,例如[/notification-service/pom.xml](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/notification-service/pom.xml#L79)。 ``` org.springframework.cloud spring-cloud-netflix-hystrix-stream ``` **[进一步了解Netflix Hystrix](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/netflix%20hystrix%20basic.md)** ## 配置Netflix Feign PiggyMetrics多次用到了Feign,使用为在客户端中添加如下代码,例如[StatisticsServiceClient.java](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClient.java)。 ```   @FeignClient(name = "auth-service")     ## 声明一个认证服务的一个客户端,通过注册中心去查找auth-service public interface AuthServiceClient { @RequestMapping(method = RequestMethod.POST, value = "/uaa/users", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) void createUser(User user); } ``` Feign同时可以引用注册中心以外的服务没,例如在统计服务模块,Feign引入了一个汇率客户端[ExchangeRatesClient.java](https://github.com/cloudframeworks-springcloud/PiggyMetrics/blob/master/statistics-service/src/main/java/com/piggymetrics/statistics/client/ExchangeRatesClient.java)。 ``` @FeignClient(url = "${rates.url}", name = "rates-client") ## 声明一个汇率客户端,根据具体的url(这个可以是外部的服务) public interface ExchangeRatesClient { @RequestMapping(method = RequestMethod.GET, value = "/latest") ExchangeRatesContainer getRates(@RequestParam("base") Currency base); } ``` **[进一步了解Netflix Feign](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/blob/master/READMORE/netflix%20feign%20basic.md)** # 如何变成自己的项目 1. git clone项目到本地,并基于该项目创建自己的mvn项目 2. 将auth-service、account-service、notification-service、statistics-service替换成自己的服务 * *config、registry、gateway、monitoring代码无需修改* 3. 在config中修改统一的配置文件,比如新增服务的服务名、端口等 4. 通过mvn构建后生成镜像 5. 运行所有的镜像,参考[快速部署](#快速部署) # 生产环境 生产环境中的应用服务需要满足以下基本特征:   1. 部分软件、硬件或网络异常后,应用依然能够可靠工作   2. 多用户支持下应用继续工作   3. 可添加或删除资源来适应不同需求变化   4. 便于部署和监控 换句话说,在生产环境下,我们需要考虑更多、更复杂的因素以满足实际业务及支持业务的特性。 对于微服务架构,推荐使用`Docker`+`Kubernetes`PaaS平台搭建,合理结构如下:
[为什么使用Docker?](https://yeasy.gitbooks.io/docker_practice/content/introduction/why.html) [为什么使用Kubernetes?](https://blog.gcp.expert/kubernetes-gke-introduction/) [Container, Docker, and Kubernetes](https://collectiveidea.com/blog/archives/2017/01/27/containers-docker-and-kubernetes-part-1) ## 安装Kubernetes Kubernetes提供了多种详尽的安装方式,此处不再赘述,建议参考: * [Kubernetes官方文档:Picking the Right Solution](https://kubernetes.io/docs/setup/pick-right-solution/) * [Kubernetes學習筆記](https://gcpug-tw.gitbooks.io/kuberbetes-in-action/content/) ## 部署应用至Kubernetes 服务编排(Service Orchestration)是**设计、创建和提供端到端服务的过程**,常常出现在面向服务架构、虚拟化、配置、融合基础架构、动态数据中心等等相关内容中,目前最流行的服务编排工具非Kubernetes(K8s)莫属。 Kubernetes将组成应用的容器组合为逻辑单元,以便于管理和发现。它的功能十分完善,提供包括资源调度、服务发现、运行监控、扩容缩容、负载均衡、灰度升级、失败冗余、容灾恢复、DevOps等一系列选项,帮助实现大规模、分布式、高可用的Docker集群,为解决业务的分布式架构、服务化设计,完整定义了构建业务系统的标准化架构层,即Cluster、Node、Pod、Label等一系列的抽象都是定义好的,为服务编排提供了一个简单、轻量级的方式。[Kubernetes: a platform for automating deployment, scaling, and operations](https://www.slideshare.net/BrianGrant11/wso2con-us-2015-kubernetes-a-platform-for-automating-deployment-scaling-and-operations) 在部署应用至Kubernetes之前,我们需要对应用的生命周期有一定了解。
* 使用Git进行代码版本管理(重点在于Git是分布式,[Git vs SVN](http://stackoverflow.com/questions/871/why-is-git-better-than-subversion)) * 明确服务的构建规则 * 采用Image或Binary应用包管理 * 制定包括开发、测试、生产及审核在内的服务部署规则 * 根据实际业务需求选择适合的发布机制([灰度发布、AB测试、蓝绿部署、金丝雀部署](http://blog.christianposta.com/deploy/blue-green-deployments-a-b-testing-and-canary-releases/)) **部署PiggyMetrics至Kubernetes** [查看PiggyMetrics应用结构图](./image/piggymetrics应用结构图.png) [查看PiggyMetrics完整Yaml文件](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/tree/master/yaml) **步骤:** 1. 安装Kubernetes、Docker环境 2. 创建命名空间 ``` kubectl -s 127.0.0.1:8080 create namespace springcloud ``` 3. 配置容器DNS ([查看dns/dns-addon.yaml文件](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/tree/master/yaml/dns)) ``` kubectl -s 127.0.0.1:8080 create -f dns/dns-addon.yaml文件 --namespace=springcloud ``` 4. 创建服务 ([查看svc/yaml文件](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/tree/master/yaml/svc)) ``` kubectl -s 127.0.0.1:8080 create -f svc/yaml文件 --namespace=springcloud ``` 5. 创建应用部署 ([查看deployment/yaml文件](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/tree/master/yaml/deployment)) ``` kubectl -s 127.0.0.1:8080 create -f deployment/yaml文件 --namespace=springcloud ``` 备注: 127.0.0.1:8080----kubernetes api server svc/yaml文件----svc部署yaml文件 deployment/yaml文件----deployment部署yaml文件 ## 功能特性实现 ### 配置中心高可用 在生产环境中服务从配置中心读取文件,而配置中心从Gitlab读取配置文件,将配置中心做成一个集群化微服务即可实现高可用,满足大量服务的需求。 结构图如下:
### 服务注册发现机制 在生产环境中服务注册发现管理采用Eureka Server进行,并**采用3个对等节点进行两两注册以实现高可用**。 结构图如下:
### 服务容错机制 通过Hystrix进行熔断处理,同时通过Hystrix Dashboard实现图形化展示,并**加入RabbitMQ使其由默认的主动“拉”的方式,变为通过MQ消息队列进行“推”的模式**,以保证简单结构和实时效率。 结构如下图所示:
### 日志采集 在生产环境中通过**EFKA**(elasticsearch fluentd kibana kafka)进行日志收集和展示。 结构如下图所示:
### 监控体系 通过实时的日志收集系统获取日志信息,并利用时间窗口的技术进行日志分析。 结构如下图所示:
## Spring Cloud性能优化 在生产环境中,我们可按照以下几点进行性能优化: 1、注册中心配置优化 eureka: instance: prefer-ip-address: true client: registerWithEureka: false fetchRegistry: false server: waitTimeInMsWhenSyncEmpty: 0 server eviction-interval-timer-in-ms: 4000 enableSelfPreservation: false renewalPercentThreshold: 0.9 2、zuul配置优化 ribbon: ReadTimeout: 20000 ConnectTimeout: 20000 MaxAutoRetries: 1 zuul: host: connect-timeout-millis: 20000 socket-timeout-millis: 20000 3、Feign配置 #请求和响应GZIP压缩支持 feign.compression.request.enabled=true feign.compression.response.enabled=true #支持压缩的mime types feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048 # 常见问题 任何相关问题均可通过[GitHub ISSUE](https://github.com/cloudframeworks-springcloud/user-guide-springcloud/issues/new)提交或讨论,问题总结请查看[[QA](QA.md)] # 更新计划 * `文档` 增加在线演示 * `文档` 增加&完善文档外链 * `组件` 单个组件深入讲解 * `常见问题` 问题汇总 点击查看[历史更新](CHANGELOG.md) # 社群贡献 + QQ群: 531980120 + [参与贡献](CONTRIBUTING.md) + [联系我们](mailto:info@goodrain.com) ------- [云框架](ABOUT.md)系列主题,遵循[APACHE LICENSE 2.0](LICENSE.md)协议发布。