针对这个架构图我分层介绍一下:nginx
一、是web服务器的选型,这个我选择的是nginx+keepalived,haproxy也是一个选择,可是haproxy在反向代理处理跨域访问的时候问题不少。因此咱们nginx有些地方作了keep-alive模式处理,减小了三次握手的次数,提升了链接效率。keepalived作nginx的负载,虚拟一个vip对外,两个nginx作高可用,nginx自己反向代理zuul集群。git
二、api gateway,这里的zuul不少人诟病,说是速度慢推荐直接用nginx,这里我仍是推荐使用zuul的,毕竟zuul含有拦截器和反向代理,在权限管理、单点登陆、用户认证时候仍是颇有用的,并且zuul自带ribbon负载均衡,若是你直接用nginx,还须要单独作一个feign或者ribbon层,用来作业务集群的负载层,毕竟直接把接口暴露给web服务器太危险了。这里zuul带有ribbon负载均衡和hystrix断路器,直接反向代理serviceId就能够代理整个集群了。web
三、业务集群,这一层我有些项目是分两层的,就是上面加了一个负载层,下面是从service开始的,底层只是单纯的接口,controller是单独一层由feign实现,而后内部不一样业务服务接口互调,直接调用controller层,只能说效果通常,多了一次tcp链接。因此我推荐合并起来,由于作过spring cloud项目的都知道,feign是含有ribbon的,而zuul也含有ribbon,这样的话zuul调用服务集群,和服务集群间接口的互调都是高可用的,保证了通信的稳定性。Hystrix仍是要有的,没有断路器很难实现服务降级,会出现大量请求发送到不可用的节点。固然service是能够改造的,若是改形成rpc方式,那服务之间互调又是另一种状况了,那就要作成负载池和接口服务池的形式了,负载池调用接口池,接口池互相rpc调用,feign client只是经过实现接口达到了仿rpc的形式,不过速度表现仍是不错的。redis
四、redis缓存池,这个用来作session共享,分布式系统session共享是一个大问题。同时呢,redis作二级缓存对下降整个服务的响应时间,而且减小数据库的访问次数是颇有帮助的。固然redis cluster仍是redis sentinel本身选择。spring
五、eurake注册中心这个高可用集群,这里有不少细节,好比多久刷新列表一次,多久监测心跳什么的,都很重要。docker
六、spring admin,这个是很推荐的,这个功能很强大,能够集成turbine断路器监控器,并且能够定义全部类的log等级,不用单独去配置,还能够查看本地log日志文件,监控不一样服务的机器参数及性能,很是强大。它加上elk动态日志收集系统,对于项目运维很是方便。数据库
七、zipkin,这个有两种方式,直接用它本身的功能界面查看方式,或者用stream流的方式,由elk动态日志系统收集。可是我必需要说,这个对系统的性能损害很是大,由于链路追踪的时候会形成响应等待,并且等待时间很是长接近1秒,这在生产环境是不能忍受的,因此生产环境最好关掉,有问题调试的时候再打开。json
八、消息队列,这个必须的,分布式系统不可能全部场景都知足强一致性,这里只能由消息队列来做为缓冲,这里我用的是Kafka。后端
九、分布式事物,我认为这是分布式最困难的,由于不一样的业务集群都对应本身的数据库,互相数据库不是互通的,互相服务调用只能是相互接口,有些甚至是异地的,这样形成的结果就是网络延迟形成的请求等待,网络抖动形成的数据丢失,这些都是很可怕的问题,因此必需要处理分布式事物。我推荐的是利用消息队列,采起二阶段提交协议配合事物补偿机制,具体的实现须要结合业务,这里篇幅有限就不展开说了。api
十、config配置中心,这是颇有必要的,由于服务太多配置文件太多,没有这个很难运维。这个通常利用消息队列创建一个spring cloud bus,由git存储配置文件,利用bus总线动态更新配置文件信息。
十一、实时分布式日志系统,logstash收集本地的log文件流,传输给elasticsearch,logstash有两种方式,一、是每一台机器启动一个logstash服务,读取本地的日志文件,生成流传给elasticsearch。二、logback引入logstash包,而后直接生产json流传给一个中心的logstash服务器,它再传给elasticsearch。elasticsearch再将流传给kibana,动态查看日志,甚至zipkin的流也能够直接传给elasticsearch。这个配合spring admin,一个查看动态日志,一个查看本地日志,同时还能远程管理不一样类的日志级别,对集成和运维很是有利。
最后要说说,spring cloud的不少东西都比较精确,好比断路器触发时间、事物补偿时间、http响应时间等,这些都须要好好的设计,并且能够优化的点很是多。好比:http通信可使用okhttp,jvm优化,nio模式,数据链接池等等,均可以很大的提升性能。
还有一个docker问题,不少人说不用docker就不算微服务。其实我我的意见,spring cloud自己就是微服务的,只须要jdk环境便可。编写dockerfile也无非是集成jdk、添加jar包、执行jar而已,或者用docker compose,将多个不一样服务的image组合run成容器而已。可是带来的问题不少,好比通信问题、服务器性能损耗问题、容器进程崩溃问题,固然若是你有一套成熟的基于k8s的容器管理平台,这个是没问题的,若是没有可能就要斟酌了。而spring cloud自己就是微服务分布式的架构,因此我的仍是推荐直接机器部署的,固然好的DevOps工具将会方便不少。
服务注册到eureka
请求统一经过API网关(Zuul)来访问内部服务.
网关接收到请求后,从注册中心(Eureka)获取可用服务
由Ribbon进行均衡负载后,分发到后端具体实例
微服务之间经过Feign进行通讯处理业务
Hystrix负责处理服务超时熔断