什么是微服务架构?什么是服务注册与服务发现?
文章目录
- 基础名词
- 分布式
- 高可用
- 集群
- 什么是微服务
- 服务注册与服务发现
- SpringCloud Alibaba
- 服务关系以及调用关系
- 服务注册中心
- Nacos服务发现的领域模型
- Nacos元数据
- 生产者服务创建及注册
- 消费者服务发现及调用
- 服务负载均衡设计及实现
- LoadBalancerClient应用
- @LoadBalanced
- Ribbon负载均衡策略
- 基于Feign的远程服务调用
- Feign应用实践
基础名词
分布式
系统中的多个模块在不同服务器上部署,即可称为分布式系统,如Tomcat和数据库分别部署在不同的服务器上,或两个相同功能的Tomcat分别部署在不同服务器上。
高可用
系统中部分节点失效时,其他节点能够接替它继续提供服务,则可认为系统具有高可用性。保证系统的高可用性,可从如下几个9说起,如图所示:
为了提高可用性,我们要么提高系统的无故障时间,要么减少系统的故障恢复时间,这就需要我们知道故障的原因。这个原因通常分为两大部分:
无计划的系统故障
- 系统级故障:包括主机、操作系统、中间件、数据库、网络、电源以及外围设备。
- 自然灾害、人为破坏,以及供电问题等。
有计划的日常任务:
- 运维相关:数据库维护、应用维护、中间件维护、操作系统维护、网络维护。
- 升级相关:数据库、应用、中间件、操作系统、网络,包括硬件升级。
在进行细分一下,就是:
- 网络问题:网络链接出现问题,网络带宽出现拥塞等
- 性能问题:慢 SQL、Java Full GC、硬盘 IO 过大、CPU 飙高、内存不足等
- 安全问题:被网络攻击,如 DDoS 等。
- 运维问题:系统总是在被更新和修改,架构也在不断地被调整,监控问题等
- 管理问题:没有梳理关键服务及服务的依赖关系,运行信息没有和控制系统同步等
- 硬件问题:硬盘损坏、网卡出问题、交换机出问题、机房掉电、挖掘机问题等
集群
一个特定领域的软件部署在多台服务器上并作为一个整体提供一类服务,这个整体称为集群。在常见的集群中,客户端往往能够连接任意一个节点获得服务,并且当集群中一个节点掉线时,其他节点往往能够自动的接替它继续提供服务,这时候说明集群具有高可用性。
- 负载均衡
请求发送到系统时,通过某些方式把请求均匀分发到多个节点上,使系统中每个节点能够均匀的处理请求负载,则可认为系统是负载均衡的。 - 正向代理和反向代理
系统内部要访问外部网络时,统一通过一个代理服务器把请求转发出去,在外部网络看来就是代理服务器发起的访问,此时代理服务器实现的是正向代理;当外部请求进入系统时,代理服务器把该请求转发到系统中的某台服务器上,对外部请求来说,与之交互的只有代理服务器,此时代理服务器实现的是反向代理。简单来说,正向代理是代理服务器代替系统内部来访问外部网络的过程,反向代理是外部请求访问系统时通过代理服务器转发到内部服务器的过程。如图所示:
什么是微服务
微服务架构(MSA)的基础是将单个应用程序开发为一组小型独立服务,这些独立服务在自己的进程中运行,独立开发和部署。就是将各个业务系统的共性再进行抽取,做成独立的服务,如图所示:
服务注册与服务发现
服务消费者找到服务提供者的这种机制称为服务发现,又或者服务注册
服务发现组件应具备以下功能:
- 服务注册表:服务注册表是服务发现组件的核心(其实就是类似于上面的registry表),它用来记录各个微服务的信息,例如微服务的名称、IP、端口等。服务注册表提供查询API和管理API,查询API用于查询可用的微服务实例,管理API用于服务的注册和注销;
- 服务注册与服务发现:服务注册是指微服务在启动时,将自己的信息注册到服务发现组件上的过程。服务发现是指查询可用微服务列表及其网络地址的机制;
- 服务检查:服务发现组件使用一定机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册表中移除该实例。
SpringCloud Alibaba
Spring Cloud Alibaba 是Spring Cloud的一个子项目,致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
Spring Cloud Alibaba 默认提供了如下核心功能:
- 服务限流降级:
默认支持WebServlet、OpenFeign、RestTemplate、Spring Cloud Gateway, RocketMQ
限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics
监控。 - 服务注册与发现:
基于Spring Cloud 服务注册与发现标准,借助Nacos
进行实现,默认还集成了Ribbon
的支持。 - 分布式配置管理:
基于Nacos支持分布式系统中的外部化配置,配置更改时自动刷新。 - 消息驱动能力:
基于Spring Cloud Stream 为微服务应用构建消息驱动能力。 - 分布式事务:
使用@GlobalTransactional
注解, 高效并且对业务零侵入地解决分布式事务问题。。 - 分布式任务调度:
提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker上执行。
架构图:
服务关系以及调用关系
服务注册中心
Nacos(DynamicNaming and Configuration Service)是一个应用于服务注册与发现、配置管理的平台。它孵化于阿里巴巴,成长于十年双十一的洪峰考验,沉淀了简单易用、稳定可靠、性能卓越的核心竞争力。
nacos的安装参考:https://yutian.blog.csdn.net/article/details/118990381
https://www.jianshu.com/p/0ee9c76bd46b
https://www.jianshu.com/p/39ade28c150d
NacosServer中(这个server本质上就是一个web服务,端口默认为8848)。
Nacos服务发现的领域模型
不同namespace
是隔离的,使用Group
可以进行管理(比如多个机房多个服务,可以将同机房的服务分一个组),Cluster
是同一个Cluster
下会尽量调用自己的Cluster
服务;
各个关键字释义如下:
- Namespace: 实现隔离,默认public
- Group: 不同服务可以分到一个组,默认DEFAULT_GROUP
- Service: 微服务
- Cluster: 对指定微服务的一个虚拟划分,默认DEFAULT
- Instance: 微服务实例
Nacos元数据
- Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签(label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。
- 作用:
- 提供描述信息
- 让微服务调用更加灵活: 例如微服务版本控制
- 级别: [服务级别、集群级别、实例级别]
生产者服务创建及注册
第一步:创建工程导入依赖:
<dependencies><!--Web服务--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--服务的注册和发现(我们要讲服务注册到nacos)--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies>
第二步:创建并修改配置文件application.yml(或者application.properties),实现服务注册,关键代码如下:
server:port: 8081
spring:application:name: sca-provider #进行服务注册必须配置服务名cloud:nacos:discovery:server-addr: localhost:8848
注意:服务名不要使用下划线(“_”),应使用横杠(“-”),这是规则。
第三步:创建启动类(假如已有则无需定义),关键代码如下:
@SpringBootApplication
public class ProviderApplication {public static void main(String[] args) {SpringApplication.run(ProviderApplication.class, args);}}
第四步:启动启动类,然后刷先nacos服务,检测是否服务注册成功,如图所示:
第五步:停掉sca-provider服务,然后不断刷新nacos服务列表,检查服务的健康状态。
消费者服务发现及调用
第一步: 在sca-provider项目中创建服务提供方对象,基于此对象对外提供服务,例如:
package com.jt.provider.controller;/**定义Controller对象(这个对象在spring mvc中给他的定义是handler),* 基于此对象处理客户端的请求*/@RestControllerpublic class ProviderController{//@Value默认读取项目配置文件中配置的内容//8080为没有读到server.port的值时,给定的默认值@Value("${server.port:8080}")private String server;//http://localhost:8081/provider/echo/tedu@GetMapping("/provider/echo/{msg}")public String doRestEcho1(@PathVariable String msg){return server+" say hello "+msg;}}
第二步:创建服务消费者工程,导入依赖:
<dependencies><!--Web服务--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--服务的注册和发现(我们要讲服务注册到nacos)--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies>
第三步:创建sca-consumer服务中的配置文件application.yml,关键代码如下:
server:port: 8090
spring:application:name: sca-consumer #服务注册时,服务名必须配置cloud:nacos:discovery:server-addr: localhost:8848 #从哪里去查找服务
第四步:创建消费端启动类并实现服务消费.
package com.jt;
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class,args);}
}
第五步:在sca-consumer启动类中添加如下方法,用于创建RestTemplate对象.
@Bean
public RestTemplate restTemplate(){//基于此对象实现远端服务调用return new RestTemplate();
}
第六步:定义sca-consumer服务的消费端Controller,在此对象方法内部实现远端服务调用
/*** 定义服务消费端Controller,在这个Controller对象* 的方法中实现对远端服务sca-provider的调用*/
@RestController
public class ConsumerController {/*** 从spring容器获取一个RestTemplate对象,* 基于此对象实现远端服务调用*/@Autowiredprivate RestTemplate restTemplate;/*** 在此方法中通过一个RestTemplate对象调用远端sca-provider中的服务* @return* 访问此方法的url: http://localhost:8090/consumer/doRestEcho1*/@GetMapping("/consumer/doRestEcho1")public String doRestEcho01(){//1.定义要调用的远端服务的urlString url="http://localhost:8081/provider/echo/8090";//2.基于restTemplate对象中的相关方法进行服务调用return restTemplate.getForObject(url, String.class);}
}
第七步:启动消费者服务,并在浏览器输入"http://localhost:8090/consumer/doRestEcho1"
地址进行访问测试。
服务负载均衡设计及实现
LoadBalancerClient应用
LoadBalancerClient对象可以从nacos中基于服务名
获取服务实例,然后在工程中基于特点算法实现负载均衡方式的调用,案例实现如下:
第一步:修改ConsumerController类,注入LoadBalancerClient对象,并添加doRestEcho2方法,然后进行服务访问.
@Autowiredprivate LoadBalancerClient loadBalancerClient;@Value("${spring.application.name:8090}")private String appName;@GetMapping("/consumer/doRestEcho02")public String doRestEcho02(){ServiceInstance serviceInstance = loadBalancerClient.choose("sca-provider");String url = String.format("http://%s:%s/provider/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);System.out.println("request url:"+url);return restTemplate.getForObject(url, String.class);}}
@LoadBalanced
当使用RestTemplate
进行远程服务
调用时,假如需要负载均衡,还可以在RestTemplate对象构建时,使用@LoadBalanced
对构建RestTemplate
的方法进行修饰,例如在ConsumerApplication
中构建名字为loadBalancedRestTemplate
的RestTemplate对象:
@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){return new RestTemplate();
}
在需要RestTemplate实现负载均衡调用的地方进行依赖注入.例如在ConsumerController类中添加loadBalancedRestTemplate属性
@Autowired
private RestTemplate loadBalancedRestTemplate;
接下来,可以在对应的服务端调用方的方法内,基于RestTemplate借助服务名进行服务调用, 例如:
@GetMapping("/consumer/doRestEcho3")
public String doRestEcho03(){String url=String.format("http://%s/provider/echo/%s","sca-provider",appName);//向服务提供方发起http请求,获取响应数据return loadBalancedRestTemplate.getForObject(url,//要请求的服务的地址String.class);//String.class为请求服务的响应结果类型
}
RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalancer,核心代码如下所示(了解):
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {final URI originalUri = request.getURI();String serviceName = originalUri.getHost();return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
}
@LoadBalanced
注解是属于Spring
,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。
Ribbon负载均衡策略
基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。如图所示:
Ribbon实现客户端负载均衡
通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:
服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。
服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。
这样,我们就可以将服务提供者的高可用以及服务消费者的负载均衡调用一起实现了。
基于Feign的远程服务调用
Feign:负载均衡(基于服务端)*
Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现。如图所示:
Feign应用实践
第一步:在服务消费方,添加项目依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:在启动类上添加@EnableFeignClients注解
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {...}
第三步:定义Http请求API,基于此API借助OpenFeign访问远端服务
什么是微服务架构?什么是服务注册与服务发现?相关推荐
- 微服务_SpringCloud微服务架构实战:高并发微服务架构设计
高并发微服务架构设计 作为一个 IT 从业人员,我们经常会碰到类似于下面的一些问题: 单个项目巨大而沉重,难以维护. 系统稳定性得不到更有效的保证. 怎样才能持续地提升系统的性能. 怎样才能快速地响应 ...
- 基于docker部署的微服务架构(九): 分布式服务追踪 Spring Cloud Sleuth
为什么80%的码农都做不了架构师?>>> 前言 微服务架构中完成一项功能经常会在多个服务之间远程调用(RPC),形成调用链.每个服务节点可能在不同的机器上甚至是不同的集群上,需 ...
- 万字长文解析:分布式架构、SOA、微服务架构、API网关、ESB服务总线架构之间的关联及演进
1架构演进 架构十五年:改变的是形态,不变的是目的 业务驱动架构形态变化 过去十几年,随着互联网发展以及业务的多样化,系统的架构也在不断发生变化,总体上来说大体经历了从单体应用架构-垂直应用架构-分布 ...
- Spring Cloud构建微服务架构(六)高可用服务注册中心
前言 在Spring Cloud系列文章的开始,我们就介绍了服务注册与发现,其中,主要演示了如何构建和启动服务注册中心Eureka Server,以及如何将服务注册到Eureka Server中,但是 ...
- 微服务架构设计模式~根据业务能力进行服务拆分
业务能力定义了一个组织的工作 组织的业务能力通常是指这个组织的业务是做什么,它们通常是稳定的. 与之相反,组织采用何种方式来实现它的业务能力,是随着时间不断变化的. 识别业务能力 一个组织有哪些业务能 ...
- consul java 注册中心_Spring Cloud微服务架构实战之Consul注册中心02:consul入门案例...
获取springcloud实战项目详细视频教程,请留言联系. 1.创建项目 我们创建聚合项目来讲解 Consul,首先创建一个 pom 父工程. 2.添加依赖 pom.xml 4.0.0 com.ex ...
- Nginx服务架构初探(七):nginx邮件服务
为什么80%的码农都做不了架构师?>>> nginx邮件服务1.邮件服务配置 一般配置在mail块中的server块中1>listen 127.0.0.1:110 配置邮 ...
- JAVA网格化服务架构,高级进阶必看 Java服务网格化系列-Kubernetes
Java开发的前景毋庸置疑,一直处于编程排行榜首位的Java语言,吸引越来越多的年轻人去学习这门有含金量的技术,对于有基础的学习者或者开发者来说,进阶学习更深入的知识对未来的职业发展非常有帮助,然而能 ...
- Dubbo和Spring Cloud微服务架构对比
一.为什么要使用微服务? 微服务提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合. 今天我们来了解下业内主要的微服务框架:Dubbo 和 Spring Cloud 微服务主要的优势 降 ...
- 微服务架构下静态数据通用缓存机制
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源 | my.oschina.net/u/3971241/bl ...
最新文章
- 1732 Fibonacci数列 2
- 数据包分析中Drop和iDrop的区别
- C 库函数 int fprintf(FILE *stream, const char *format, ...) 发送格式化输出到流 stream 中
- 怎么测内阻 恒压源_测电压表内阻的六种方法
- 安卓访问mysql的源码_【原创源码】安卓数据库简单操作demo
- man命令手册打开以后的使用方法
- 面试题之第一部分(Python基础篇) 80题
- wordpress改变ip或域名
- User status for Service Order
- java orm框架什么意思_ORM框架是什么
- linux 对象管理器,Linux多安全策略和动态安全策略框架模块详细分析之函数实现机制中文件对象管理器分析(3)...
- setBackgroundResource的一个问题
- 谈谈JVM内部锁升级过程
- 毕昇 JDK:为啥是ARM 上超好用的 JDK
- windows bat与vbs与reg脚本整合 持续更新
- 创建表 备注 修改表结构 修改约束
- juniper防火墙命令大全(中文)
- oracle11g64位精简版客户端,oracle11g 64位|oracle11g 64位客户端下载 附安装教程 - 121下载站...
- pygame学习笔记(6)——一个超级简单的游戏
- 留在一线城市还是回老家?一个8年北漂的4点思考