「java实现服务治理」java服务开发
本篇文章给大家谈谈java实现服务治理,以及java服务开发对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、饿了么分布式服务治理及优化经验
- 2、java框架有哪些常用框架?
- 3、如何用java 建立一个分布式系统
- 4、Spring Cloud笔记03: 服务注册和服务发现的基本概念
- 5、关于服务治理的一点理解
- 6、SpringCloud之Eureka Feign简介
饿了么分布式服务治理及优化经验
饿了么框架部门技术总监,前爱立信首席软件工程师,10 年以上高可用性,高并发系统架构设计经验。现饿了么框架工具部负责人,负责饿了么中间件的设计及实施,通过中间件以及研发工具的辅助提升研发人员的工作效率,提升网站的稳定性及性能。
今天我想站在一个大的角度上,看一下饿了么最近一年多的时间,经历的技术上一些痛苦的问题与改进的过程。
为什么讲比较痛苦的事情?昨天和一位专家聊天受益很大,他说人在什么时候能够自我驱动?就是痛苦的时候。 只有感到痛苦,才会有改变。 当然改变有两种结果,一种是彻底放弃沉沦,另外就是一想办法自动化、智能化,把自己变成一个高手。
MVP 原则
我现在也很痛苦,但是还没有放弃。先讲一下 MVP 原则,MVP(Minimum Viable Product) 现在比较火, 一个产品是做大而全,还是可用就行? 我从去年 3 月份加入饿了么,开始组建框架和工具的团队。中间件里面很多东西都可以去做,但是我真的需要把所有的东西都做全吗还是 MVP 原则就好?这是我们思考的一个问题。
MVP 的意思就是做一个最小可用的就可以,大家以前很流行说,“世界那么大,我想去看看”,其实框架很多东西看看就好,做全做好是需要长时间积累的,我们缺的恰恰是时间。我们要做的就是立足现状,解决痛点问题。现在饿了么的现状说白了比百废待兴好一点。 当有太多事情可以去做的情况下,更需要抓住重点,不死人的尽量不要去踏。
服务治理的现状
服务治理是一个很大的话题,它涵盖了很多内容,比如前面晓波老师介绍的 Redis 治理、姚捷老师讲的链路监控系统(参看文末文章),都可以涵盖在里面。
编程语言
先介绍语言,刚才会场一些人说他们是异构的语言,但可能还是没有饿了么这么复杂。饿了么语言主要有两种,Python 及 Java,原来整个公司语言都是以 Python 为主,可以说是上海最大的 Python 大厂。为什么不坚持用 Python?不是说 Python 语言不好,而是招不到人。在业务急速发展的时候怎么办?换 Java 语言就成了自然的选择。
在我进公司的时候,其实不仅仅是这两种语言,还有 PHP,C 语言等。基于这些现状,框架的选择点就比较少。因此做了一些妥协,SOA 的框架有两套,主要是为 Python 和 Java 做的,Python 的叫 Vespense,Java 版本的叫 Pylon,Vespense 和 Pylon 都是星际争霸里面的两种最基本的东西,没有这两种东西游戏根本打不下去。
java框架有哪些常用框架?
十大常用框架:
一、SpringMVC
二、Spring
三、Mybatis
四、Dubbo
五、Maven
六、RabbitMQ
七、Log4j
八、Ehcache
九、Redis
十、Shiro
延展阅读:
一、SpringMVC
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
模型(Model )封装了应用程序的数据和一般他们会组成的POJO。
视图(View)是负责呈现模型数据和一般它生成的HTML输出,客户端的浏览器能够解释。
控制器(Controller )负责处理用户的请求,并建立适当的模型,并把它传递给视图渲染。
Spring的web模型 - 视图 - 控制器(MVC)框架是围绕着处理所有的HTTP请求和响应的DispatcherServlet的设计。
Spring Web MVC处理请求的流程
具体执行步骤如下:
1、 首先用户发送请求————前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;
2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;
3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;
4、 前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。
二、Spring
2.1、IOC容器:
IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。在Spring中BeanFactory是IOC容器的实际代表者。
2.2、AOP:
简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系
AOP用来封装横切关注点,具体可以在下面的场景中使用:
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
三、Mybatis
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
总体流程:
(1)加载配置并初始化
触发条件:加载配置文件
将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求 触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。
MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。
四、Dubbo
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用协议)远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。
1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。
2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
3、 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
五、Maven
Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包。但是对于我们程序员来说,我们最关心的是它的项目构建功能。
六、RabbitMQ
消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。
Erlang是一门动态类型的函数式编程语言。对应到Erlang里,每个Actor对应着一个Erlang进程,进程之间通过消息传递进行通信。相比共享内存,进程间通过消息传递来通信带来的直接好处就是消除了直接的锁开销(不考虑Erlang虚拟机底层实现中的锁应用)。
AMQP(Advanced Message Queue Protocol)定义了一种消息系统规范。这个规范描述了在一个分布式的系统中各个子系统如何通过消息交互。
七、Log4j
日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。
八、Ehcache
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。
优点:
1、 快速
2、 简单
3、 多种缓存策略
4、缓存数据有两级:内存和磁盘,因此无需担心容量问题
5、 缓存数据会在虚拟机重启的过程中写入磁盘
6、可以通过RMI、可插入API等方式进行分布式缓存
7、 具有缓存和缓存管理器的侦听接口
8、支持多缓存管理器实例,以及一个实例的多个缓存区域
9、提供Hibernate的缓存实现
缺点:
1、使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。
2、 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。
九、Redis
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis数据库完全在内存中,使用磁盘仅用于持久性。相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。Redis可以将数据复制到任意数量的从服务器。
1.2、Redis优点:
(1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
(2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
1.3、Redis缺点:
(1)单线程
(2)耗内存
十、Shiro
Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。Shiro的具体功能点如下:
(1)身份认证/登录,验证用户是不是拥有相应的身份;
(2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
(3)会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
(4)加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
(5)Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
(6)shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
(7)提供测试支持;
(8)允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
(9)记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
如何用java 建立一个分布式系统
分布式架构的演进
系统架构演化历程-初始阶段架构
初始阶段 的小型系统 应用程序、数据库、文件等所有的资源都在一台服务器上通俗称为LAMP
特征:
应用程序、数据库、文件等所有的资源都在一台服务器上。
描述:
通常服务器操作系统使用Linux,应用程序使用PHP开发,然后部署在Apache上,数据库使用MySQL,汇集各种免费开源软件以及一台廉价服务器就可以开始系统的发展之路了。
系统架构演化历程-应用服务和数据服务分离
好景不长,发现随着系统访问量的再度增加,webserver机器的压力在高峰期会上升到比较高,这个时候开始考虑增加一台webserver
特征:
应用程序、数据库、文件分别部署在独立的资源上。
描述:
数据量增加,单台服务器性能及存储空间不足,需要将应用和数据分离,并发处理能力和数据存储空间得到了很大改善。
系统架构演化历程-使用缓存改善性能
特征:
数据库中访问较集中的一小部分数据存储在缓存服务器中,减少数据库的访问次数,降低数据库的访问压力。
描述:
系统访问特点遵循二八定律,即80%的业务访问集中在20%的数据上。
缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况。
系统架构演化历程-使用应用服务器集群
在做完分库分表这些工作后,数据库上的压力已经降到比较低了,又开始过着每天看着访问量暴增的幸福生活了,突然有一天,发现系统的访问又开始有变慢的趋势了,这个时候首先查看数据库,压力一切正常,之后查看webserver,发现apache阻塞了很多的请求,而应用服务器对每个请求也是比较快的,看来 是请求数太高导致需要排队等待,响应速度变慢
特征:
多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
描述:
使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,提升系统的并发处理能力,使得服务器的负载压力不再成为整个系统的瓶颈。
系统架构演化历程-数据库读写分离
享受了一段时间的系统访问量高速增长的幸福后,发现系统又开始变慢了,这次又是什么状况呢,经过查找,发现数据库写入、更新的这些操作的部分数据库连接的资源竞争非常激烈,导致了系统变慢
特征:
多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
描述:
使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,使得服务器的负载压力不在成为整个系统的瓶颈。
系统架构演化历程-反向代理和CDN加速
特征:
采用CDN和反向代理加快系统的 访问速度。
描述:
为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。CDN与反向代理的基本原理都是缓存。
系统架构演化历程-分布式文件系统和分布式数据库
随着系统的不断运行,数据量开始大幅度增长,这个时候发现分库后查询仍然会有些慢,于是按照分库的思想开始做分表的工作
特征:
数据库采用分布式数据库,文件系统采用分布式文件系统。
描述:
任何强大的单一服务器都满足不了大型系统持续增长的业务需求,数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
分布式数据库是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。
系统架构演化历程-使用NoSQL和搜索引擎
特征:
系统引入NoSQL数据库及搜索引擎。
描述:
随着业务越来越复杂,对数据存储和检索的需求也越来越复杂,系统需要采用一些非关系型数据库如NoSQL和分数据库查询技术如搜索引擎。应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。
系统架构演化历程-业务拆分
特征:
系统上按照业务进行拆分改造,应用服务器按照业务区分进行分别部署。
描述:
为了应对日益复杂的业务场景,通常使用分而治之的手段将整个系统业务分成不同的产品线,应用之间通过超链接建立关系,也可以通过消息队列进行数据分发,当然更多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。
纵向拆分:
将一个大应用拆分为多个小应用,如果新业务较为独立,那么就直接将其设计部署为一个独立的Web应用系统
纵向拆分相对较为简单,通过梳理业务,将较少相关的业务剥离即可。
横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务
横向拆分需要识别可复用的业务,设计服务接口,规范服务依赖关系。
系统架构演化历程-分布式服务
特征:
公共的应用模块被提取出来,部署在分布式服务器上供应用服务器调用。
描述:
随着业务越拆越小,应用系统整体复杂程度呈指数级上升,由于所有应用要和所有数据库系统连接,最终导致数据库连接资源不足,拒绝服务。
Q:分布式服务应用会面临哪些问题?
A:
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
(4) 服务多了,沟通成本也开始上升,调某个服务失败该找谁?服务的参数都有什么约定?
(5) 一个服务有多个业务消费者,如何确保服务质量?
(6) 随着服务的不停升级,总有些意想不到的事发生,比如cache写错了导致内存溢出,故障不可避免,每次核心服务一挂,影响一大片,人心慌慌,如何控制故障的影响面?服务是否可以功能降级?或者资源劣化?
Java分布式应用技术基础
分布式服务下的关键技术:消息队列架构
消息对列通过消息对象分解系统耦合性,不同子系统处理同一个消息
分布式服务下的关键技术:消息队列原理
分布式服务下的关键技术:服务框架架构
服务框架通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务启用
服务框架是一个点对点模型
服务框架面向同构系统
适合:移动应用、互联网应用、外部系统
分布式服务下的关键技术:服务框架原理
分布式服务下的关键技术:服务总线架构
服务总线同服务框架一样,均是通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务启用
服务总线是一个总线式的模型
服务总线面向同构、异构系统
适合:内部系统
分布式服务下的关键技术:服务总线原理
分布式架构下系统间交互的5种通信模式
request/response模式(同步模式):客户端发起请求一直阻塞到服务端返回请求为止。
Callback(异步模式):客户端发送一个RPC请求给服务器,服务端处理后再发送一个消息给消息发送端提供的callback端点,此类情况非常合适以下场景:A组件发送RPC请求给B,B处理完成后,需要通知A组件做后续处理。
Future模式:客户端发送完请求后,继续做自己的事情,返回一个包含消息结果的Future对象。客户端需要使用返回结果时,使用Future对象的.get(),如果此时没有结果返回的话,会一直阻塞到有结果返回为止。
Oneway模式:客户端调用完继续执行,不管接收端是否成功。
Reliable模式:为保证通信可靠,将借助于消息中心来实现消息的可靠送达,请求将做持久化存储,在接收方在线时做送达,并由消息中心保证异常重试。
五种通信模式的实现方式-同步点对点服务模式
五种通信模式的实现方式-异步点对点消息模式1
五种通信模式的实现方式-异步点对点消息模式2
五种通信模式的实现方式-异步广播消息模式
分布式架构下的服务治理
服务治理是服务框架/服务总线的核心功能。所谓服务治理,是指服务的提供方和消费方达成一致的约定,保证服务的高质量。服务治理功能可以解决将某些特定流量引入某一批机器,以及限制某些非法消费者的恶意访问,并在提供者处理量达到一定程度是,拒绝接受新的访问。
基于服务框架Dubbo的服务治理-服务管理
可以知道你的系统,对外提供了多少服务,可以对服务进行升级、降级、停用、权重调整等操作
可以知道你提供的服务,谁在使用,因业务需求,可以对该消费者实施屏蔽、停用等操作
基于服务框架Dubbo的服务治理-服务监控
可以统计服务的每秒请求数、平均响应时间、调用量、峰值时间等,作为服务集群规划、性能调优的参考指标。
基于服务框架Dubbo的服务治理-服务路由
基于服务框架Dubbo的服务治理-服务保护
基于服务总线OSB的服务治理-功能介绍
基于服务总线OSB的服务治理
Q:Dubbo到底是神马?
A:
淘宝开源的高性能和透明化的RPC远程调用服务框架
SOA服务治理方案
Q:Dubbo原理是?
A:
-结束-
Spring Cloud笔记03: 服务注册和服务发现的基本概念
上节在K8S集群中部署了Nacos集群,并将Nacos的Web控制台和API以Ingress (nacos.youcomany.com)的形式暴露到了k8s集群外部,便于从外部测试和访问。 这里再次强调Nacos被设计为一个在IDC内部使用的应用组件,而非面向公网环境的产品,因此需要在内部隔离网络中使用,这里为了测试将其暴露到K8S集群外部,如果是生产环境必须做好网络安全策略。
接下来我们将学习如何将服务注册到Nacos,在开始后边的实战之前,先看一下服务治理中关于服务注册和服务发现的一些概念。
服务治理首先要解决的问题就是服务注册于服务发现,解决了这两个问题才可能实现微服务之间的调用问题。
服务注册中心 : 每个服务实例会向注册中心注册自己的信息,一般包含地址、端口、协议、版本等信息。每种服务会有多个实例副本注册到注册中心,注册中心维护每种服务的多个实例列表。同时,注册中心会以某种机制去检查各个服务实例是否可用,如果某个实例已经失效会将其剔除。在某个服务实例关闭时会自动向注册中心注销自己。
常见的服务注册有三种实现方式:
服务发现 : 即服务客户端在其网络上找到其要调用服务的具体连接信息的过程。例如通过查询服务注册中心得到其所调用服务的具体 IP地址和端口。 简单的说,服务发现就是服务或者应用之间互相定位的过程。
使用服务发现后,客户端对服务的调用不再和具体的服务实例地址耦合,而是基于服务发现机制。有以下4种常见的服务发现机制:
K8S中的一个Service资源对象对应微服务。每个Service有唯一的名字,一个ClusterIP,一个端口。 K8S中的Pod资源对象中运行的容器对应服务实例,通过Pod上的标签Label和Service上定义的标签选择器Label Selector将Service与Pod关联,通过Service内建的负载均衡机制,对Service的调用将转发到Pod的容器中。 K8S中的服务注册是在Pod创建时由调度者Kubernetes完成的。K8S中的服务发现采用的是服务端负载均衡器,服务注册中心为Kubernetes(后端持久化存储etcd)。
Spring Cloud对微服务提供了完整的解决方案和统一抽象,按照微服务的功能特性: 服务治理、负载均衡、服务间调用通信、服务配置中心、服务网关、分布式链路追踪、消息总线、消息时间驱动、分布式事务等,提供了一系列组件,被称为Spring Cloud全家桶。 全家桶中的功能组件还支持使用第三方实现的某个组件单独替换,只要第三方组件是遵循Spring Cloud Common的抽象实现的。
Spring Cloud在服务治理的组件上有以下三种选择:
当然由于"某些原因",在最新版本的Spring Cloud中Netflix组件库已经逐渐被移除。
我们在这里对Spring Cloud服务注册和服务发现的学习将使用Spring Cloud Alibaba组件的Nacos。
Nacos是Spring Cloud Alibaba提供的服务发现和配置管理的解决方案。Nacos是用Java开发的,通过Spring Cloud Alibaba可以很好的与Spring Cloud整合。 如果项目的所有微服务都是用Java开发的,那么使用Nacos作为服务发现可能会使一个不错的选择。
Nacos的服务注册采用的是由"服务进程内直接包含服务注册模块,由服务实例自己完成上线注册和下线注销。",这与K8S服务注册方案中"由一个中间调度者K8S来帮助处理服务注册"是不同的。
关于服务治理的一点理解
服务治理是随着微服务一起出现的。在远古时代的单体服务,所有业务部署在一个进程,共享相同的资源,包括机器、网络等资源。所以业务之间通信或者交互简单。但是微服务中的每个服务都有自己独立的资源,服务之间交互就变得复杂多了。服务独立了,问题也随之而来。怎么知道其他服务在哪(服务发现),能不能提供服务(注册中心或者服务探活),资源如何调度(资源调度)、服务如何通信(流量治理)等等问题如何解决,服务治理应运而生。
我们在日常中想要管理或者解决一些人或者事情,需要尽可能地了解对方,才能进行。所以想要服务治理,我们也要了解服务。但是需要了解哪些方面呢?
我们可以通过指标来了解服务状态。指标可以分为两种:基础指标和业务指标。
基础指标主要是一些通用的指标。下面是一些常见的基础指标:
• 机器指标(cpu、内存、网络)
• jvm metric
• pod metric
• 基础组件指标(db metric、redis metric等)
业务指标是指和业务相关的指标。这些指标反映了业务的状态。比如业务处理延迟、速度等。
我们在管理服务时需要知道服务需要哪些资源,需要多少。这样我们才能给服务分配资源。资源调度的前提是:我们知道还剩多少资源。所以我们需要基础指标。只有基础指标健全,我们才能获得剩余资源的信息,才能进行资源调度。目前资源调度一般都是用k8s来管理。
服务正常运行需要其依赖的服务正常运行。所以我们需要知道服务的依赖关系,调用链情况。通过调用链我们可以知道依赖关系,业务瓶颈在哪,哪些业务是关键业务,需要扩缩容。
常见的调用链中间:jeager、skywalking、zipkin。在选型时,优先考虑业务入侵小的方案,例如Java 字节码技术。
随着服务数量的增加,管理的难度也随之剧增。所以我们需要搭建基础设施来辅助管理。
k8s 是目前最火的服务编排系统,我们也就在赘述了。
配置中心是为服务提供配置的,我们可以通过配置中心对服务进行管理,比如业务使用哪套算法模型,业务出现线程数量等。常见的配置中心有:zookeeper、consul、Nacos、apollo、spring cloud config。
zookeeper和consul 只具有简单的配置中心功能,相当于nosql db。在服务体量不大,服务治理场景简单的时候可以使用。但是对于复杂或者高级的服务治理场景还是捉襟见肘。比如灰度发布。
Nacos、apollo、spring cloud config 提供了配置中心高级功能:配置推送,配置刷新,配置隔离等。有如下场景的时优先从三者中选择:
• 多环境(开发、测试、线上)
• 多租户
• 灰度发布
• 资源隔离
注册中心的本质是服务探活。注册中心会对外提供可用服务地址查询。比如gprc 可以使用注册中心查询存活实例,然后做负载均衡。在spring cloud 中的feign的负载均衡也都是基于注册中心。
服务治理的最终目标就是实现自动化。但是自动化是建立在前面两项之上的,拥有必要的数据我们才能自动化。
流量治理有两种主要场景:激增大流量和灰度发布。激增大流量可以通过自动扩缩容解决,我们后面在说。
不同版本配置不同:这个问题需要使用配置中心解决。
不同版本流量不同:service mesh 可以解决这个问题。
要实现自动扩缩容,我们就需要知道哪些服务需要扩缩容。我们需要定义一系列指标,用于衡量服务。
负载负载情况:我们可以监控pod cpu 情况;api 调用时长P99情况;api 调用频率情况。
流量情况:api 调用数量;网络情况。
通过各种指标我们可以知道服务状态,从而我们可以指定扩缩容规则。
上面提到的每项技术都能展开讲很久,之后的文章我们在详细聊聊。
SpringCloud之Eureka Feign简介
1、Eureka注册中心
现在公司项目大多采用前后端分离架构,服务层被拆分成了很多的微服务,为方便管理Spring Cloud给我们提供了服务注册中心来管理微服务。
1.1、Eureka简介
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提
供服务端与客户端,服务端即是Eureka服务注册中心,客户端完成微服务向Eureka服务的注册与发现。服务端和
客户端均采用Java语言编写。下图显示了Eureka Server与Eureka Client的关系:
Eureka Server是服务端,负责管理各各微服务结点的信息和状态。
在微服务上部署Eureka Client程序,远程访问Eureka Server将自己注册在Eureka Server。
微服务需要调用另一个微服务时从Eureka Server中获取服务调用地址,进行远程调用。
1.2、Eureka Server搭建
1.2.1、单机环境搭建
1、父工程引入Maven依赖:
org.springframework.cloud
spring‐cloud‐dependencies
Finchley.SR1
pom
import
2、在Eureka Server工程添加:
org.springframework.cloud
spring‐cloud‐starter‐netflix‐eureka‐server
3、在SpringBoot启动类添加@EnableEurekaServer注解,标识这是一个Eureka服务:
@EnableEurekaServer//标识这是一个Eureka服务
@SpringBootApplication
publicclassGovernCenterApplication{
publicstaticvoidmain(String[] args){
SpringApplication.run(GovernCenterApplication.class, args);
}
}
4、在application.yml中配置Rureka:
server:
port:50101#服务端口
spring:
application:
name:xc‐govern‐center#指定服务名
eureka:
client:
registerWithEureka:false#服务注册,是否将自己注册到Eureka服务中
fetchRegistry:false#服务发现,是否从Eureka中获取注册信息
serviceUrl:#Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
defaultZone:
server:
enable‐self‐preservation:false#是否开启自我保护模式,开发模式建议关闭
eviction‐interval‐timer‐in‐ms:60000#服务注册表清理间隔(单位毫秒,默认是60*1000)
5、启动Eureka Server,浏览50101端口:
上图红色提示信息:
THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF
NETWORK/OTHER PROBLEMS.
自我保护模式被关闭。在网络或其他问题的情况下可能不会保护实例失效。
Eureka Server有一种自我保护模式,当微服务不再向Eureka Server上报状态,Eureka Server会从服务列表将此
服务删除,如果出现网络异常情况(微服务正常),此时Eureka server进入自保护模式,不再将微服务从服务列
表删除。
至此,Eureka服务端已经搭建完成,下面进行服务注册,将微服务注册到Eureka服务端进行管理。
1.3、服务注册
1、在需要注册的微服务中,添加依赖:
org.springframework.cloud
spring‐cloud‐starter‐netflix‐eureka‐client
2、配置application.yml:
eureka:
client:
registerWithEureka:true#服务注册开关
fetchRegistry:true#服务发现开关
serviceUrl:#Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
defaultZone:${EUREKA_SERVER:}
instance:
prefer‐ip‐address:true#将自己的ip地址注册到Eureka服务中
ip‐address:${IP_ADDRESS:127.0.0.1}
instance‐id:${spring.application.name}:${server.port}#指定实例id
3、启动类上加注解@EnableDiscoveryClient ,表示它是一个Eureka的客户端
4、刷新Eureka Server查看注册情况
同理可将需要注册的服务注册到Eureka Server。
2、Feign远程调用
服务层被拆分成了很多的微服务,服务与服务之间难免发生交互调用,这时候就需要用到远程调用,接下来带大家入门及使用
2.1Ribbon
1、简介
Ribbon是Netflix公司开源的一个负载均衡的项目(),它是一个基于HTTP、TCP的客户端负载均衡器,通过负载均衡来实现系统的高可用、集群扩容等功能。
如下图是服务端负载均衡架构图:
用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。
客户端负载均衡架构图:
客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。
2、测试Ribbon
Spring Cloud引入Ribbon配合 restTemplate 实现客户端负载均衡。Java中远程调用的技术有很多,如:webservice、socket、rmi、Apache HttpClient、OkHttp等,互联网项目使用基于http的客户端较多,下面介绍使用的是OkHttp。
首先加入Maven依赖:
!--如果依赖了spring-cloud-starter-eureka,会自动添加spring-cloud-starter-ribbon依赖--
org.springframework.cloud
spring‐cloud‐starter‐ribbon
com.squareup.okhttp3
okhttp
在application.yml中配置Ribbon参数:
ribbon:
MaxAutoRetries:2#最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试
MaxAutoRetriesNextServer:3#切换实例的重试次数
OkToRetryOnAllOperations:false#对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
ConnectTimeout:5000#请求连接的超时时间
ReadTimeout:6000#请求处理的超时时间
负载均衡测试:
启动两个cms服务,端口要不一致
定义RestTemplate,使用@LoadBalanced注解:
@Bean
@LoadBalanced
publicRestTemplaterestTemplate(){
returnnewRestTemplate(newOkHttp3ClientHttpRequestFactory());
}
远程调用cms的查询页面接口:
//负载均衡调用
@Test
publicvoidtestRibbon(){
//服务id
String serviceId ="XC‐SERVICE‐MANAGE‐CMS";
for(inti=0;i10;i++){
//通过服务id调用
ResponseEntity forEntity = restTemplate.getForEntity("http://"+ serviceId
+"/cms/page/get/5a754adf6abb500ad05688d9", CmsPage.class);
CmsPage cmsPage = forEntity.getBody();
System.out.println(cmsPage);
}
}
添加@LoadBalanced注解后,restTemplate会走LoadBalancerInterceptor拦截器,此拦截器中会通过RibbonLoadBalancerClient查询服务地址,打断点观察每次调用的服务地址和端口,可以看到两个cms服务会轮流被调用。
2.2Feign
简介:
Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
使用:
添加Maven依赖:
dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring‐cloud‐starter‐openfeign/artifactId
/dependency
dependency
groupIdcom.netflix.feign/groupId
artifactIdfeign‐okhttp/artifactId
/dependency
定义FeignClient接口:
@FeignClient(value = "XC_SERVICE_MANAGE_CMS")
publicinterfaceCmsPageClient{
//微服务接口路径
@GetMapping("/cms/page/get/{id}")
publicCmsPagefindById(@PathVariable("id")String id);
}
启动类添加@EnableFeignClients注解
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
publicclassFeignTest{
@Autowired
CmsPageClient cmsPageClient;//接口代理对象,由Feign生成代理对象
@Test
publicvoidtestFeign(){
//发起远程调用
CmsPage cmsPage = cmsPageClient.findById("5a754adf6abb500ad05688d9");
System.out.println(cmsPage);
}
}
Feign工作原理:
1、 启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象
2、 @FeignClient(value = XcServiceList.XC_SERVICE_MANAGE_CMS)即指定了cms的服务名称,Feign会从注册中心获取cms服务列表,并通过负载均衡算法进行服务调用。
3、在接口方法 中使用注解@GetMapping("/cms/page/get/{id}"),指定调用的url,Feign将根据url进行远程调用。
关于java实现服务治理和java服务开发的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。