网站 多语言,制作网站的分类,商业网站建立,装潢设计与制作是学什么SpringCloudNetflix入门
一、应用架构的演变
伴随互联网的发展#xff0c;使用互联网的人群越来越多#xff0c;软件应用的体量越来越大和复杂。而传统单体应用 可能不足以支撑大数据量以及发哦并发场景应用的框架也随之进行演变从最开始的单体应用架构到分布式#xff08…SpringCloudNetflix入门
一、应用架构的演变
伴随互联网的发展使用互联网的人群越来越多软件应用的体量越来越大和复杂。而传统单体应用 可能不足以支撑大数据量以及发哦并发场景应用的框架也随之进行演变从最开始的单体应用架构到分布式SOA架构到 今天比较火的微服务框架以及微服务网格架构。
单体–分布式–SOA–微服务–…
1、单体应用
1.1 什么是单体应用
传统的应用就是单体架构即所有的模块、组件等都在一个应用中最终打包(war,jar)使用一个容器(如Tomcat)进行部署且通常一个应用享用一个数据库。 将单体应用分为三个组成部分持久层、业务层、表现层。单体应用在初期业务少没有问题单体应用需求不断增多也伴随着业务逻辑、业务组件等日益扩张应用将会变得越来越臃肿往后的开发和维护就会变得特别麻烦再着越来越大访的问量并发越来越高面对海量的用户无论从应用性能还是从数据库方面都有吃不消的时候。所以单体应用在数据量、并发量到一定程度时一定会遇到瓶颈。
1.2 单体框架的优缺点
1.2.1 单体项目缺点
代码臃肿不方便开发维护(代码可读性差)代码编译系统启动变慢系统扩展性能变差(牵一发而动全身)无法针对某一个业务做扩展(集群)对大数据量,高并发量的处理不占优势技术选型单一模块/业务耦合度高
1.2.2 单体项目的优点
易于开发 架构简单技术成本低易于测试 所有功能在一个项目方便测试易于部署 一个Tomcat就可以实现部署简单方便
1.3 单体应用于集群
问题引入 在单体架构中为提升应用的并发 和 防止单节点故障一个Tomcat挂应用就挂了通常就会做集群。
1.3.1 什么是集群
集群多个单体项目合成一个集群 这里的集群指复制多个相同应用共同工作来提高作业能力多个应用做相同的事。 1.3.2 单体应用于集群带来的问题
当应用做集群就会存在多个应用节点这些节点将会暴露多个访问地址ip:port那么客户端是不知道该访问那个应用节点的 为解决客户端不知道访问那个应用节点就需要有一个请求分发的功能的组件负载均衡器将将客户端的请求相对平均的分发多个应用节点上这就是负载均衡而这个做请求分发的组件就是负载均衡器。 这里的Nginx就是一个负载均衡器它可按某种算法轮询、ip_hash等清请求路由分发到不同的后端服务器上同类型负载均衡器有 HAproxy、LVS等。 负载均衡算法如轮询、随机、权重。 每个功能模块使用并发数量不同有些模块使用特别多有些模块使用的量少 解决思路将重复的功能提取成模块可根据需求量做集群这些模块组合成一个完整的项目。 上图描述 每个模块就是一个项目每个项目都可以单独的做技术选型、部署、运维、维护其实该图就是一个简单的微服务了
1.4 单体项目的举例
前端分离
2.分布式于SOA
2.1 分布式架构
2.2 面向服务的架构SOA
3. 微服务架构
3.1 什么是微服务
微服务架构可以认识为 是一种SOA架构上的一种发展最早由“Martin Fowler”提出
就目前而言对于微服务业界并没有一个统一的、标准的定义While there is no precise definition of this architectural style ) 。但通常而言微服务架构是一种架构模式或者说是一种架构风格它提倡将单一应用程序划分成一组小的服务每个服务运行独立的自己的进程中服务之间互相协调、互相配合为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建并且能够被独立地部署到生产环境、类生产环境等。另外应尽量避免统一的、集中式的服务管理机制对具体的一个服务而言应根据业务上下文选择合适的语言、工具对其进行构建可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务也可以使用不同的数据存储。从“Martin Fowler”提出观点来看微服务架构 和 SOA 架构很像。总体来说微服务就是把单体应用进行进行细粒度的拆分分成多个小(微)的服务每个服务独立运行每个服务只需要专注一个业务即可并且每个服务都可以有自己的数据库(分库)服务之间互协调配合完成整个系统的业务。 简单的来说微服务就是将一个单体项目根据需求拆分为多个模块每个模块就是一个项目每个项目都可以单独的做 技术选型、部署、运维、维护。再根据每个模块的并发量做集群。 微服务机构图 微服务做集群 微服务特点 由多个服务组成完整的系统每个服务都是独立的有自己的进程服务之间使用HTTP协议通信不同的服务可以使用不同的编程语言不同的服务的数据库可以多样化选择微服务是一个分布式系统 微服务拆分做集群带来的问题 模块之间需要通讯对于集群服务需要负载均衡事务 怎么解决session怎么处理识别当前的用户问题 解决问题的办法 SpringCloudSpringCloud Alibaba它们是解决微服务拆分带来的一系列问题
3.2 微服务的优缺点
优点 单个服务业务简单代码简单方便开发维护服务之间无耦合服务之间升级维护互不影响轻量级HTTP通信机制使得的不同的服务可以采用不同的编程语言微服务有极强的扩展能力,业务量大的服务可以再次拆分服务也可以进行集群部署剔除服务也很方便更大的系统负载能力和容错能力(集群)对于开发人员来说,通常只需要关注单一服务,新员工上手也比较快微服务架构对现在流行的敏捷开发支持优化 缺点 分布式事务 服务通信机制增加了事务的复杂性架构师要选择合适的分布式方案(CAP理论)部署麻烦 微服务众多部署麻烦需要借助容器技术和自动化部署工具这又增加了开发人员的学习成本。技术成本高 微服务架构本身比较复杂,技术成本高开发人员需要花更多的时间学习相关技术。服务通信对性能的损耗 微服务架构一定要考虑服务通信延迟对服务调用性能的损耗问题开发人员需要选择合适的通信方式解决这一问题。
3.3 如何选型
大型项目选择微服务,如电商物流售票等系统我们可以选择使用微服务架构中小型项目选择单体
二、SpringCloud 介绍
1、认识SpringCloud
SpringCloud 是一个基于SpringBoot实现的服务治理工具包用于微服务架构中 管理和协调服务的。Spring Cloud是一系列框架的有序集合。SpringCloud 利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等都可以用Spring Boot的开发风格做到一键启动和部署。SpringCloud 通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。SpringCloud让微服务架构的落地变得更简单。
2、SpringCloud常用组件
采用微服务后就会引发一些列的难题需要去解决如 众多微服务的通信地址应该如何管理微服务之间应该使用何种方式发起调用微服务故障该如何处理众多微服务的配置文件如何集中管理等 SpringCloud为这一系列的难题提供了相应的组件来解决如下图SpringCloud最核心 Netfli Eureka注册中心 Eureka 是用来管理微服务的通信地址清单有了Eureka后就可通过服务名字 实现 服务的调用。 Netflix Ribbon/Feign (远程调用客户端负载均衡) Ribbon 与 Feign 都是客服端负载均衡器。作用服务发生调用时将请求按某种规则分发到多个目标服务器上。简单理解激素是解决微服务之间的通信问题。 Netflix Hystrix断路器/熔断器 有时一个请求需要多个微服务共同完成那么一旦某个服务发生故障导致整个调用链上的微服务全都出现异常甚至导致整个微服务架构瘫痪。作用Hystrix就是解决微服务故障保护服务安全的组件。 Netflix Zuul服务网关 zuul作为服务网关可将它看作是微服务的大门所有的请求都需要经过zuul之后才能到达目标服务。据zuul特性可将微服务公共的事情交个zuul统一处理。如用户鉴权、请求监控。 Spring Cloud Config 分布式配置/配置中心 微服务架构中的服务实例非常的多而服务的配置文件分散在每个服务中每次修改服务的配置文件和重新服务实例都是一个很麻烦的工作。Spring Cloud Config作为分布式配置管理中心就是用来统一的管理服务的配置文件。 Spring Cloud Bus消息总线 消息总线是在微服务中给各个微服务广播消息的一个组件我们使用消息总线构建一个消息中心其他微服务来接入到消息中心当消息总线发起消息接入的微服务都可以收到消息从而进行消费。 Spring Cloud sleuth微服务链路追踪 应用采用微服务架构之后后台可能有几十个甚至几百个服务在支撑一个请求请求可能需要多次的服务调用最后才能完成。作用就是来监控维护之间的调用关系,让程序员方便直观的感受到一个请求经历了哪些微服务以及服务的请求时间是否有异常等。
3、SpringCloud的版本
SpringCloud是基于SpringBoot的,所以两者的jar包都需要导入。注意SprinbCloud的版本需要和SpringBoot的版本兼容。我的项目 SpringBoot版本是2.0.5.RELEASESpringCloud的版本是Finchley.SR1
Release TrainSpringBoot VersionHoxton2.2.xGreenwich2.1.xFinchley2.0.xEdgware1.5.xDalston1.5.x
4、服务通信协议
1RPC
RPC(Remote Produce Call)远程过程调用类似的还有RMI。自定义数据格式基于原生TCP通信速度快效率高。早期的webservice、现在dubbo都是RPC的典型
2Http
Http其实是一种网络传输协议基于TCP规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议。也可用来进行远程服务调用。缺点是消息封装臃肿。Rest风格就可以通过http协议来实现
三、 SpringCloud与Dubbo
1、Dubbo简介
Dubbo最早是阿里巴巴提供的一个服务治理和服务调用框架现在已经成为Apache的顶级项目。
四、服务注册与发现
1、什么是Eureka
帮助管理服务的通信地址。
2、Eureka的工作原理
1服务注册
Eureka 是一个 服务 注册与发现的组件就是用来统一管理微服务的通信地址的组件它包含 EurekaServer服务器注册中心和 EurekaClient客户端组成。EurekaServer是独立的服务而 EurekaClient需要集成到每个微服务中。微服务EurekaClient在启动时会向EurekaServer提交自己的服务信息如服务名,ip,端口等在在 EurekaServer会形成一个微服务的通信地址列表存储起来。----这个过程服务注册
2服务发现
微服务(EurekaClient)会定期(RegistryFetchIntervalSeconds:默认30s)的从EurekaServer拉取一份微服务通信地址列表缓存到本地。当一个微服务在向另一个微服务发起调用的时候会根据目标服务的服务名找到其通信地址然后基于HTTP协议向目标服务发起请求。—这叫服务发现
3服务续约
微服务(EurekaClient)采用定时(LeaseRenewalIntervalInSeconds:默认30s)发送“心跳”请求向EurekaServer发请求进行服务续约其实就是定时向 EurekaServer发请求报告自己的健康状况告诉EurekaServer自己还活着不要把自己从服务地址清单中剔除掉那么当微服务(EurekaClient)宕机未向EurekaServer续约或者续约请求超时注册中心机会从服务地址清单中剔除该续约失败的服务。
4服务下线
微服务(EurekaClient)关闭服务前向注册中心发送下线请求注册中心(EurekaServer)接受到下线请求负责将该服务实例从注册列表剔除。
5Eureka工作流程 3、EurekaServer实例
1多模块项目结构 所有的jar包交给父工程管理现在主要用到
spring-cloud-parent //父项目--Project
pom.xml //父项目的pomservice-eureka-server-11000 //注册中心EurekaServer service-user-server-31000 //用户服务EurekaClient ,提供者--modelservice-order-server-21000 //订单服务EurekaClient ,消费者--model2Spring-cloud-parent父项目管理依赖在pom.xml文件中
参考文档https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__quick_start.html#_client_side_usagespringcloud-parent父工程负责管理SpringBoot和SpringCloud的jar包
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.lfg/groupIdartifactIdspring-cloud-parent/artifactIdpackagingpom/packagingversion1.0-SNAPSHOT/versionmodulesmoduleservice-eureka-11000/modulemoduleservice-order-21000/modulemoduleservice-user-31000/module/modules!--公共的一些配置--propertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingjava.version1.8/java.version/properties!--1.管理 SpringBoot的jar包--!--SpringBoot--parentgroupIdorg.springframework.boot/groupIdversion2.2.5.RELEASE/versionartifactIdspring-boot-starter-parent/artifactId/parent!--2.管理 SpringCloud的jar包--dependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversionHoxton.SR3/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagement
/project3搭建EurasiaServer----service-eureka-server-11000
参考文档https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi_spring-cloud-eureka-server.html#netflix-eureka-server-starter在springcloud-parent父工程下面搭建springcloud-eureka-server-11000然后集成EurekaServer
a.service-eureka-server-11000项目结构 b.在pom.xml文件引入依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd!--集成自己的父工程--parentartifactIdspring-cloud-parent/artifactIdgroupIdcom.lfg/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdservice-eureka-11000/artifactIddependencies!--导入springboot 基础包--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--导入EurekaServer包--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-eureka-server/artifactId/dependency/dependencies
/project提示 spring-cloud-starter-netflix-eureka-server EurekaServer端的基础依赖同时也把EurekaClient端也导入进来了 spring-boot-starter-web web服务的基础依赖是不可缺少的
c.配置启动类
package cn.lfg2000;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/*** 注册中心启动类* EnableEurekaServer : 开启EurekaServer服务端*/
SpringBootApplication
EnableEurekaServer
public class EurekaServerApp {public static void main(String[] args) {SpringApplication.run(EurekaServerApp.class);}
}d.配置application.yml配置文件
server:port: 11000 #端口号
eureka:instance:hostname: localhost #主机名client: #客户端配置register-with-eureka: false #false:EurekaServer自己不要注册到EurekaServer自己 只有EurekaClient才注册fetch-registry: false #EurekaServer不要拉取服务的通信地址列表 只有EurekaClient才拉取地址列表service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/server: #注册中心的注册地址enable-self-preservation: false #关闭自我保护警告e.启动测试
启动springcloud-eureka-server-11000浏览器访问http://localhost:11000若出现下面界面Eureka注册成功 4、Eureka自我保护
默认情况下当EurekaServer接收到服务续约的心跳失败比例在15分钟之内低于85%EurekaServer会把这些服务保护起来即不会把该服务从服务注册地址清单中剔除掉但是在此种情况下有可能会出现服务下线那么消费者就会拿到一个无效的服务请求会失败那我们需要对消费者服务做一些重试或在熔断策略。当EurekaServer开启自我保护时监控主界面会出现红色警告信息我们可以使用eureka.server.enable-self-preservationfalse来关闭EurekaServer的保护机制这样可以确保注册中心中不可用的实例被及时的剔除但是不推荐
5、EurekaClient实例
参考文档 https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__service_discovery_eureka_clients.html#netflix-eureka-client-starterservice-user-server-31000 与 service-order-server-21000 两个都是EurekaClient客户端都需要去集成EurekaClient,。
1service-user-server-31000–用户服务
a.service-user-server-31000 项目结构 b.在pom.xml文件引入依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspring-cloud-parent/artifactIdgroupIdcom.lfg/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdservice-user-31000/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-eureka-client/artifactId/dependency/dependencies
/project同步顺序执行异步不用等待上一步的执行完才执行下一步可以先执行下一步再执行上一步。
c.配置启动类
package cn.lfg2000;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/*** 用户的启动类* EnableEurekaClient 标记该应用是 EurekaClient客户端*/
SpringBootApplication
EnableEurekaClient //或者EnableDiscoveryClient
public class UserApp {public static void main(String[] args) {SpringApplication.run(UserApp.class);}
}d.配置 application.yml配置文件
#端口号
server:port: 31001
#指定服务的名字
spring:application:name: service-user
#注册到EurekaServer
eureka:client:serviceUrl:defaultZone: http://localhost:11000/eureka/instance: #使用ip进行注册instance-id: service-user:31001 #实例IDprefer-ip-address: true #开启使用指定ip进行注册e.启动测试 2service-order-server-21000–订单服务
操作流程与用户服务一致。启动类 和 配置文件需要修改
a.启动类
package cn.lfg2000;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;SpringBootApplication
EnableEurekaClient
public class OrderApp {public static void main(String[] args) {SpringApplication.run(OrderApp.class);}
}b.application.xml
server:port: 21000
spring:application:name: service-order
eureka:client:service-url:defaultZone: http://localhost:11000/eurekainstance:prefer-ip-address: true #启动ip注册 默认使用计算机的名字注册instance-id: service-order:21000五、RestTemplate 服务通信
1、服务通信流程以订单服务通信用户服务为例 调用关系浏览器—订单服务—用户服务订单服务通过RestTemplate向用户服务发起调用目的是要获取到用户服务返回的User对象最终是需要浏览器获取到User。
2、RestTemplate介绍
微服务的通信协议主流的有RPC,HttpSpringCloud是基于Http Restful 风格 在Java中发起一个Http请求的方式很多比如 Apache的HttpClient OKHttp等等 。Spring为我们封装了一个基于Restful的使用非常简单的Http客户端工具 RestTemplate 我们就用它来实订单服务和用户服务的通信。需要注意的是RestTmplate本身不具备服务发现和负载均衡器的功能案例只是演示在订单服务中使用RestTemplate基于ip和端口的方式向用户服务发起调用即不走注册中心不使用服务发现方式。
3、编码实现RestTemplate
1搭建公共模块–service-entity
该模块用户存放实体类
a.service-entity 项目结构 b.在pom.xml文件中引入依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspring-cloud-parent/artifactIdgroupIdcom.lfg/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdservice-entity/artifactIddependenciesdependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency/dependencies
/projectc.创建实体类
User
package cn.lfg2000.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;NoArgsConstructor
AllArgsConstructor
Data
public class User {private Long id;private String username;
}Order
package cn.lfg2000.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;NoArgsConstructor
AllArgsConstructor
Data
public class Order {private Long id;private String desc;private Double price;private User user;
}d.在用户模块、订单模块引入server-entity模块
dependencygroupIdcom.lfg/groupIdartifactIdservice-entity/artifactIdversion1.0-SNAPSHOT/version
/dependencye.在用户模块的controller层编写执行方法
package cn.lfg2000.controller;import cn.lfg2000.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
//用户服务暴露接口给订单访问
RestController
public class UserController {// 将用户服务的端口号注入port中Value(${server.port})private Integer port;//订单服务来调用这个方法 http://localhost:31001/user/1GetMapping(/user/{id})public User getUserById(PathVariable(id) long id){// 模拟一个user对象return new User(id,一个人哭port);}
}f.在订单模块的controller层中编写执行方法并获取User对象
编写配置类RestTemplate
package cn.lfg2000.config;import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;Configuration
public class RestTemplateConfig {//配置一个RestTemplate Spring封装的一个机遇Restful风格的http客户端 工具Bean/*LoadBalanced*/public RestTemplate getRestTemplate(){return new RestTemplate();}/*Beanpublic RandomRule getRandomRule(){return new RandomRule();}*/
}订单模块controller层执行方法
package cn.lfg2000.controller;import cn.lfg2000.pojo.Order;
import cn.lfg2000.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;RestController
public class OrderController {Autowiredprivate RestTemplate restTemplate;GetMapping(/order/{id})public Order getOrder(PathVariable(id) long id){String url http://localhost:31001/user/id;User user restTemplate.getForObject(url, User.class);return new Order(id,一刀999,99.99,user);}
}g.测试 六、Ribbon客户端负载均衡
1、为什么要Ribbon
为了防止应用出现单节点故障问题同时为了提高应用的作业能力我们需要对应用做集群 如果我们对user-server(用户服务)做了集群 那么这个时候回衍生出一些问题现在有两个user-server(用户服务)就意味着有两个user-server(用户服务)的通信地址我的order-server(订单服务)在向user-server(用户服务)发起调用的时候该访问哪个如何访问这个时候就需要有一个组件帮我们做请求的分发即负载均衡器而Ribbon就是一个 - 客户端负载均衡器。
2、什么是Ribbon
Ribbon是Netflix发布的云中间层服务开源项目主要功能是提供客户端负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时重试等。简单来说Ribbon是一个客户端负载均衡器Ribbon可以按照负载均衡算法(如简单轮询随机连接等)向多个服务发起调用(正好可以解决上面的问题)我们也很容易使用Ribbon实现自定义的负载均衡算法。
3、Ribbon的工作机制
如下图我们将用户服务)做集群处理增加到2个节点(注意两个用户服务的服务名要一样ip和端口不一样)在注册中心的服务通信地址清单中user-server(用户服务)这个服务下面会挂载两个通信地址 。 真实操作就是修改application.yml配置文件中的端口号再运行启动类就好了 订单服务 会定时拉取通信地址清单到本地进行缓存当订单服务想用户服务发起调用时需要指定服务名为 service-user这时Ribbon根据service-user这个服务名找到两个service-user通信地址然后根据Ribbon会按照负载均衡算法morning轮询选择其中的某个通信地址发起和http请求实现服务的调用。 4、提供者service-user(用户服务)集群
1服务集群方案
使用SpringBoot多环境配置方式集群一个配置文件配置多个service-userr环境需要注意的是集群中的多个服务名(spring.application.name)应该一样我们把相同的东西提取到最上面不同的东西配置在各自的环境中
2用户服务集群配置
真实操作就是修改application.yml配置文件中的端口号再运行启动类就好了第一个service-user
#注册到EurekaServer
eureka:client:serviceUrl:defaultZone: http://localhost:11000/eureka/instance: #使用ip进行注册instance-id: service-user:31001prefer-ip-address: true #开启使用指定ip进行注册
#端口号
server:port: 31001
#指定服务的名字
spring:application:name: service-user第二个service-user修改application.yml 并启动
#注册到EurekaServer
eureka:client:serviceUrl:defaultZone: http://localhost:11000/eureka/instance: #使用ip进行注册instance-id: service-user:31000 #实例IDprefer-ip-address: true #开启使用指定ip进行注册
#端口号
server:port: 31000
#指定服务的名字
spring:application:name: service-user5、消费者service-order集成Ribbon
Ribbon 集成官方文档https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi_spring-cloud-ribbon.html#netflix-ribbon-starter
1在service-order服务的pom.xml中引入依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-ribbon/artifactId
/dependency2开启负载均衡
LoadBalanced开启负载均衡的能力修改RestTemplate的Bean的定义方法
package cn.lfg2000.config;import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;Configuration
public class RestTemplateConfig {//配置一个RestTemplate Spring封装的一个机遇Restful风格的http客户端 工具BeanLoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}/*Beanpublic RandomRule getRandomRule(){return new RandomRule();}*/
}3修改service-order服务controller层的执行方法
package cn.lfg2000.controller;import cn.lfg2000.pojo.Order;
import cn.lfg2000.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;RestController
public class OrderController {Autowiredprivate RestTemplate restTemplate;GetMapping(/order/{id})public Order getOrder(PathVariable(id) long id){String url http://service-user/user/id;User user restTemplate.getForObject(url, User.class);return new Order(id,一刀999,99.99,user);}
}6、测试 七、Ribbon负载均衡算法
1、Ribbon内置算法 2、配置负载均衡算法
1注解全局配置
/*** 订单的启动类*/
SpringBootApplication
EnableEurekaClient
public class OrderServerApplication1030
{//配置一个RestTemplate Spring封装的一个机遇Restful风格的http客户端 工具//LoadBalanced :让RestTemplate有负载均衡的功能BeanLoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}//负载均衡算法Beanpublic RandomRule randomRule(){return new RandomRule();}//省略...3yml方式配置负载均衡算法
a.配置全局Ribbon算法
ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRuleb.配置某个服务的Ribbon算法
service-user:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule八、Ribbon调优配置
1、超时配置 使用Ribbon进行服务通信时为了防止网络波动造成服务调用超时我们可以针对Ribbon配置超时时间以及重试机制 也可以针对具体的服务进行超时配置如服务名.ribbon…
ribbon:ReadTimeout: 3000 #读取超时时间ConnectTimeout: 3000 #链接超时时间MaxAutoRetries: 1 #重试机制同一台实例最大重试次数MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数OkToRetryOnAllOperations: false #是否所有操作都重试因为针对post请求如果没做幂等处理可能会造成数据多次添加/修改2、饥饿加载
我们在启动服务使用Ribbon发起服务调用的时候往往会出现找不到目标服务的情况这是因为Ribbon在进行客户端负载均衡的时候并不是启动时就创建好的而是在实际请求的时候才会去创建所以往往我们在发起第一次调用的时候会出现超时导致服务调用失败我们可以通过设置Ribbon的饥饿加载来改善此情况即在服务启动时就把Ribbon相关内容创建好。
ribbon:eager-load:enabled: true #开启饥饿加载clients: user-server #针对于哪些服务需要饥饿加载3yml方式配置负载均衡算法
a.配置全局Ribbon算法
ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRuleb.配置某个服务的Ribbon算法
service-user:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule八、Ribbon调优配置
1、超时配置 使用Ribbon进行服务通信时为了防止网络波动造成服务调用超时我们可以针对Ribbon配置超时时间以及重试机制 也可以针对具体的服务进行超时配置如服务名.ribbon…
ribbon:ReadTimeout: 3000 #读取超时时间ConnectTimeout: 3000 #链接超时时间MaxAutoRetries: 1 #重试机制同一台实例最大重试次数MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数OkToRetryOnAllOperations: false #是否所有操作都重试因为针对post请求如果没做幂等处理可能会造成数据多次添加/修改2、饥饿加载
我们在启动服务使用Ribbon发起服务调用的时候往往会出现找不到目标服务的情况这是因为Ribbon在进行客户端负载均衡的时候并不是启动时就创建好的而是在实际请求的时候才会去创建所以往往我们在发起第一次调用的时候会出现超时导致服务调用失败我们可以通过设置Ribbon的饥饿加载来改善此情况即在服务启动时就把Ribbon相关内容创建好。
ribbon:eager-load:enabled: true #开启饥饿加载clients: user-server #针对于哪些服务需要饥饿加载