九 springcloud微服务

本文介绍 SpringCloud 微服务架构,涵盖 Eureka、Ribbon、Feign、Hystrix、Zuul、Config、Bus、Stream 和 Sleuth 等核心组件的功能与实现方式。探讨微服务的优势及挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springcloud微服务

什么是微服务?

简单来说,微服务就是把几个类似相似的功能放在一起, 对外提供接口调用,不论是前端调用,还是后端别的系统调用,只要他能尽到自己的职责,为他们提供服务,那么这就是微服务。服务之间彼此可以通过http调用,或者RestTemplate调用。

为什么使用微服务?

传统的单体架构虽然开发简单,部署简单(甚至不需要运维)。但是可扩展性差,不利于业务拆分,如果要对某个模块做集群水平扩展,那么是不行的;技术代码耦合度高,不能进行子模块技术升级或者改造。模块耦合度高可用性低。

优点业务上容易拆分,扩展性强,一定程度解决高并发。维护独立服务模块不需要下线其他服务,其他服务还是可以继续运行,只需要重新部署某个独立的服务即可。此外,只要有需求,就尽管去拆服务,或者新增功能点,都能以一个独立的服务去开发,如此-来服务的扩展性是非常强大的。就譬如,我们目前项目的业务划分力度比较大, -方面电脑配置不高,一方 面划分越多;也越复杂,比如admin中,完全可以把友情链接和文章领域再单独的拆两个服务出来也是完全可以的。如此一来,打包部署都是独立的,是的职能划分更加清晰。
缺点拆分的服务很多,需要维护的团队人数众多,拆分使得业务更复杂。所以开发维护成本都是比较大的。分布式下的技术成本高,比如分布式事务,分布式锁,服务容错、监控等等。

RestTemplate 弊端(eureka解决):

1.域名有问题,在本地配置,如果在生产环境,那么这里会使用内网ip,但是有同学会问,只要域名备案解析不就可以用吗?这是不行的,用域名就会走公网,所以这里往往都是写内网IP。
2.接着1来说,如果全部都写ip,那么如果有成百上千个服务,那么这些ip岂不是要写几千个?那怎么.办?把这些ip写进一个静态类吗? 那如果要修改ip怎么办?重启服务器吗?这样的硬编码肯定也不好,不够灵活,耦合也大。
3.再者,如果服务很多,有几百上千个,那么这些调用关系越来越多越来越服务站那么就很难去维护和管理。

Eureka

在这里插入图片描述

其中为了保证注册中心以及服务的高可用,他们都可以以集群的形态出现。使用注册中心不仅简化了调用关系,并且保证了服务之间的可靠调用以及服务的集群高可用。同时也符合了解耦的目的。

角色:

eureka server:注册中心,所有的服务包括都会把相关信息注册进去。这么一来,所有可用的微服务节点信息都可以在管理界面中看到。

eureka client: 注册客户端,每个微服务个体都是客户端,其实也就是一个web工程。 其中服务的调用肪称之为消费者(consumer),被调用方称之为服务提供者(provider)。每个微服务和eureka之间都会保持心跳,如果心跳断了,则会剔出该服务。

实现方式:

  1. 在pom中引入eureka-server依赖
  2. yml中配置eureka信息
  3. 启动类上开启eureka server注解
  4. 访问http://eureka:7000/
  5. 在用户端配置eureka cilent

配置成功后:调用方式发生改变

String userServerUrl = "http://user.imoocnews.com:8003/user/queryByIds?userIds=" + JsonUtils.objectToJson(idSet);
ResponseEntity<GraceJSONResult> responseEntity = restTemplate.getForEntity(userServerUrlExecute, GraceJSONResult.class);

String serviceId = "SERVICE-USER";
List<ServiceInstance> instanceList = discoveryClient.getInstances(serviceId);
ServiceInstance userService = instanceList.get(0);
    
String userServerUrlExecute
        = "http://" + userService.getHost() + ":" + userService.getPort() + "/user/queryByIds?userIds=" + JsonUtils.objectToJson(idSet);

可以同时构建eureka与微服务的集群实现,同时在resttempleta上加上loadBalance为服务调用提供负载均衡的轮训方式

Ribbon

负载均衡可以把请求按照一定的规定分摊到后面的服务器集群,从而达道集群高可用以及处理并发的目的

ribbon是服务间通信的负载均衡工具。他提供了完善的超时重试机制。我们可以在客户端配置文件中列出负载均衡的服务节点,ribbon会帮我们实现负载均衡算法去调用这些微服务。Ribbon这个负载均衡是基于客户端的负载均衡,而不是服务端的负载均衡。比如nginx就是基于服务端的负载均衡。

简单总结就是: ibbo= RestTemplate + LoadBalance .这两者需要结合起来使用。同时可以自定义负载均衡算法:轮训或者随机
在这里插入图片描述

Fegin

String serviceId = "SERVICE-USER";
String url = "http://" + serviceId + "/user/queryByIds?userIds=" + JsonUtils.objectToJson(idSet);

以前:调用方式不灵活还属于硬编码范围

Fegin就是把硬编码伪装成接口service的方式去进行调用,如此一来就更加灵活了,减少了硬编码,参数也不需要拼接,整体代码风格更加舒服。feign是声明式的http工具,可以实现rest web service调用。使用feign可以使得微服务表用变的更加简洁明了。就相当于一个controller调用service的方法 那样简单。feign的底层 也是使用的ribbon做的负载均衡,springcloud都帮我们把这些组件进行了封装。

实现方式:

  1. 在pom中引入openfegin依赖
  2. 对api接口做fegin支持
  3. 启动类上开启fegin支持
GraceJSONResult bodyResult = userControllerApi.queryByIds(JsonUtils.objectToJson(idSet));

feign本身就是基于http的调用, 那么对于http调用有时候出现-些问题需要排查,那么我们是可以开启日志的,feign的日志很详细,开启后便于观察。

Hystrix

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWqnrtyu-1624713801822)(C:\Users\陈\Desktop\找工作\复习资料\慕课网\慕课网\5f7c741108cf9c9d16000726.jpg)]

​ 如上图,当一个服务不可用或者超时又或者发生异常再或者网络拥堵的时候,为了避免整个系统雪崩效应,那么我们会切断和这个系统的通信,这个骚操作叫做服务熔断,服务熔断后,这个服务对外不可用了,所以此时我们可以提供一 个兜底的方案,也就是提供一 个方法,这个方法就是弥补服务熔断后所提供的内容,这个叫做服务降级,降级也就是提供一个固定返回一 些参数或者数据的方法,比如返回:“该服务不可用,请稍等。“如此一 类的话。

模拟异常: 算术符异常、超时异常、宕机(直接关闭用户服务)

服务提供方(user):

局部降级实现方式:

  1. 在对应业务的controller.上添加注解的熔断机制,并且写上降级方法
  2. 当降级后,则调用降级代码即可
  3. 启动类开启熔断注解

全局降级方式:

  1. 在controlle上方加上@DefaultProperties(defaultFallback = “globalFallback”)

服务调用方(article):

降级实现方式:

  1. 服务调用方是通过feign实现的,所以对feign要开启对hystrix的支持 :
  2. 启动类开启hystrix注解:
  3. 在feign客户端上添加降级配置

自动触发熔断隔离与恢复:

图中标识了hystrix的几个状态,首先正常情况下,断路器是处于关闭状态(CLOSED) ,如果此时发生异常,在超过-定百分比(阈值)的异常错误,则开启断路器(OPEN)此时发生熔断,所有请求无法访问,此时访问兜底的降级方法。等待-定时间以后,断路器会慢慢释放一个请求去检测服务是否可用,此时处于半开状态(HALF OPEN),如果请求没毛病,则关闭断路器,否则继续开启断路器。如此持续重复进行检查。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BkSGl3Yn-1624713801822)(C:\Users\陈\Desktop\找工作\复习资料\慕课网\慕课网\5f7c74f408a5327716000742.jpg)]

Zuul

网关存在于用户和微服务之间,所有的外部请求都会先经过网关,然后到达微服务端,那么如此一来,对于前端来讲,他只需要知道网关地址即可。那么用户怎么访问咱们这个微服务网关呢?其实本质上也是一个rest请求。

Zuu可以作为springcloud微服务的网关来使用,他可以实现动态路由、过滤器等功能。

●动态路由:动态的把用户请求分配到不同的后端微服务。
●过滤器:校验用户请求的合法性,类似拦截器。

实现方式:

  1. 创建子工程springcloud-zuul-server
  2. 启动类开启zuul网关注解:
  3. 在yml中配置路由(路由的目的就是把用户端过来的请求分配到对应的不同的微服务中去处理。http://[网关地址]:[端口号]/[前缀]/[微服务id]/[请求路径])
  4. 将zuul注册到eureka中,配置启动类开启eureka同时在yml中配置eureka

当我们使用zuu后,那么所有前端发来的请求必定会经过zuu这个网关,需要注意,微服务之间通信不会.经过zuul,还是用的feign。整个架构图可以参考如下:可以在网关这边加过滤器,限制ip请求

在这里插入图片描述

Config

在springcloud中的很多组件都会需要在yml中进行配置,而且这些配置很多,一旦微服务很多的话,那么修改起来就很麻烦,而且容易出错,所以这个时候我们可以使用分布式管理中心config来统-进行管理和配置,如此也可以提高配置效率。

SpringCloud Config包含了服务端和客户端。
●服务端称之为分布式配置中心,也是一一个工厂,是一个微服务项目,主要用来连接配置服务器,诅把配置信息提供给客户端。
●客户端就是那些系统中的微服务,可以获得config的配置。
●配置信息我们可以统一存放到git,config服务会从git上获取然后进行统一 配置管理。SpringCloudConfig本身也是默认使用git来存储配置信息的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ms8iOL7s-1624713801823)(C:\Users\陈\Desktop\找工作\复习资料\慕课网\慕课网\5f7c75fa08281b1c16000738.jpg)]

Bus

解决config遗留的问题:

●手动刷新与业务耦合
●N个微服务端需要N次手动刷新

Bus支持rabbitmq,其实本质上就是原先我们人工手动刷新配置的操作,交给了mq,mq可以向所有订阅者发送消息,通知他们去自动刷新,这么一来,不论有多少台微服务,那么我只需要发送一个通知信 息给config,虽然config去通知其他微服务去实现配置刷新即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-em2JHGE0-1624713801824)(C:\Users\陈\Desktop\找工作\复习资料\慕课网\慕课网\5f7c779c08f2170e16000602.jpg)]

Stream

stream这个组件,这个组件相当于是基于mq的封装,通过stream就能适配所有的mq,如此我们只需要关注stream的使用,具体使用了什么mq,我们不需要关注,如此一来减少了开发维护成本,也减少了新人入职的学习成本。

●如上如所示,通过binder绑定器, 我们就能去操作切换到不同的mq了,原先我们是通过springboot去结合不同mq然后去实现代码,而现在,只需要结合binder就行,假设我们更换了mq产品,如果我们采用stream,那么我们的业务代码不需要更改,如果没有使用stream,那么所有的代码实现都得改。从中就能看出stream的优势。
●output: 消息输出通道,其实也是channel管道, 生产者把消息发送给binder。
●input:消息输入通道,也是channel管道, 生产者的消息往这里扔,binder把消息通过input发给消费者。
●理解output和input: 代码层面构建消息以后输出到binder (MQ) ,再由binder输入到另-个代码层处理消费。
●往往在编码之前先去了解熟悉模型,会更有利于编码,这也和数学公式一个道理,公式会了, 解答各种代数啊几何啊就迎刃而解。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zKmu1FFt-1624713801825)(C:\Users\陈\Desktop\找工作\复习资料\慕课网\慕课网\5f7c7829083fd34d16000661.jpg)]

支持消息的分组与持久化:使用分组后即使用户服务宕机也会在用户服务重新启动的时候接受消息

Sleuth

结合zipkin为各服务之间的请求提供可视化的链路追踪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值