SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法

这篇具有很好参考价值的文章主要介绍了SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringCloudNetflix入门

一、应用架构的演变

  • 伴随互联网的发展,使用互联网的人群越来越多,软件应用的体量越来越大和复杂。
  • 而传统单体应用 可能不足以支撑大数据量以及发哦并发场景
  • 应用的框架也随之进行演变
  • 从最开始的单体应用架构到分布式(SOA)架构到 今天比较火的微服务框架,以及微服务网格架构。

​ 单体–>分布式–>SOA–>微服务–>…

1、单体应用

1.1 什么是单体应用

  • 传统的应用就是单体架构,即所有的模块、组件等都在一个应用中,最终打包(war,jar),使用一个容器(如Tomcat)进行部署,且通常一个应用享用一个数据库。

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 将单体应用分为三个组成部分:持久层、业务层、表现层。
  • 单体应用在初期:业务少没有问题
  • 单体应用需求不断增多,也伴随着业务逻辑、业务组件等日益扩张,应用将会变得越来越臃肿往后的开发和维护就会变得特别麻烦,
  • 再着越来越大访的问量,并发越来越高,面对海量的用户无论从应用性能还是从数据库方面都有吃不消的时候。
  • 所以,单体应用在数据量、并发量到一定程度时一定会遇到瓶颈。

1.2 单体框架的优缺点

1.2.1 单体项目缺点
  • 代码臃肿不方便开发维护(代码可读性差)
  • 代码编译系统启动变慢
  • 系统扩展性能变差(牵一发而动全身)
  • 无法针对某一个业务做扩展(集群)
  • 对大数据量,高并发量的处理不占优势
  • 技术选型单一
  • 模块/业务耦合度高
1.2.2 单体项目的优点
  • 易于开发 :架构简单,技术成本低
  • 易于测试 :所有功能在一个项目,方便测试
  • 易于部署 :一个Tomcat就可以实现部署,简单方便

1.3 单体应用于集群

  • 问题引入:
    • 在单体架构中,为提升应用的并发 和 防止单节点故障(一个Tomcat挂,应用就挂了),通常就会做集群。
1.3.1 什么是集群
  • 集群:多个单体项目合成一个集群
    • 这里的集群指:复制多个相同应用共同工作来提高作业能力,多个应用做相同的事。

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

1.3.2 单体应用于集群带来的问题
  • 当应用做集群,就会存在多个应用节点,这些节点将会暴露多个访问地址(ip:port),那么客户端是不知道该访问那个应用节点的
    • 为解决客户端不知道访问那个应用节点,就需要有一个请求分发的功能的组件(负载均衡器)将将客户端的请求相对平均的分发多个应用节点上,这就是负载均衡,而这个做请求分发的组件就是负载均衡器。

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 这里的Nginx就是一个负载均衡器,它可按某种算法(轮询、ip_hash等)清请求路由分发到不同的后端服务器上,同类型负载均衡器有 HAproxy、LVS等。

  • 负载均衡算法如:轮询、随机、权重。

  • 每个功能模块使用并发数量不同,有些模块使用特别多,有些模块使用的量少

    • 解决思路:将重复的功能提取成模块,可根据需求量做集群,这些模块组合成一个完整的项目。

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 上图描述
    • 每个模块就是一个项目
    • 每个项目都可以单独的做技术选型、部署、运维、维护
    • 其实该图就是一个简单的微服务了

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 架构很像。总体来说,微服务:就是把单体应用进行进行细粒度的拆分,分成多个小(微)的服务,每个服务独立运行,每个服务只需要专注一个业务即可,并且每个服务都可以有自己的数据库(分库),服务之间互协调配合完成整个系统的业务。

  • 简单的来说,微服务:就是将一个单体项目根据需求,拆分为多个模块,每个模块就是一个项目,每个项目都可以单独的做

    技术选型、部署、运维、维护。再根据每个模块的并发量做集群。

  • 微服务机构图

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 微服务做集群
    SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 微服务特点

    • 由多个服务组成完整的系统
    • 每个服务都是独立的,有自己的进程
    • 服务之间使用HTTP协议通信
    • 不同的服务可以使用不同的编程语言
    • 不同的服务的数据库可以多样化选择
    • 微服务是一个分布式系统
  • 微服务拆分做集群带来的问题

    • 模块之间需要通讯
    • 对于集群服务,需要负载均衡
    • 事务 怎么解决
    • session怎么处理,识别当前的用户问题
  • 解决问题的办法

    • SpringCloud
    • SpringCloud 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最核心

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 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.RELEASE
    • SpringCloud的版本是Finchley.SR1
Release Train SpringBoot Version
Hoxton 2.2.x
Greenwich 2.1.x
Finchley 2.0.x
Edgware 1.5.x
Dalston 1.5.x

4、服务通信协议

(1)RPC

  • RPC(Remote Produce Call)远程过程调用,类似的还有RMI。
  • 自定义数据格式,基于原生TCP通信,速度快,效率高。
  • 早期的webservice、现在dubbo,都是RPC的典型

(2)Http

  • 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)接受到下线请求负责将该服务实例从注册列表剔除。

(5)Eureka工作流程

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

3、EurekaServer实例

(1)多模块项目结构

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 所有的jar包交给父工程管理
  • 现在主要用到
spring-cloud-parent //父项目--Project
pom.xml	//父项目的pom
	service-eureka-server-11000 //注册中心EurekaServer 
	service-user-server-31000   //用户服务EurekaClient ,提供者--model
	service-order-server-21000  //订单服务EurekaClient ,消费者--model

(2)Spring-cloud-parent(父项目)管理依赖,在pom.xml文件中

  • 参考文档:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__quick_start.html#_client_side_usage
  • springcloud-parent父工程:负责管理SpringBoot和SpringCloud的jar包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lfg</groupId>
    <artifactId>spring-cloud-parent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>service-eureka-11000</module>
        <module>service-order-21000</module>
        <module>service-user-31000</module>
    </modules>

    <!--公共的一些配置-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <!--1.管理 SpringBoot的jar包-->
    <!--SpringBoot-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <version>2.2.5.RELEASE</version>
        <artifactId>spring-boot-starter-parent</artifactId>
    </parent>

    <!--2.管理 SpringCloud的jar包
 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

(3)搭建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项目结构

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

b.在pom.xml文件,引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--集成自己的父工程-->
    <parent>
        <artifactId>spring-cloud-parent</artifactId>
        <groupId>com.lfg</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-eureka-11000</artifactId>

    <dependencies>
        <!--导入springboot 基础包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--导入EurekaServer包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-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注册成功

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

4、Eureka自我保护

  • 默认情况下,当EurekaServer接收到服务续约的心跳失败比例在15分钟之内低于85%,EurekaServer会把这些服务保护起来,即不会把该服务从服务注册地址清单中剔除掉,但是在此种情况下有可能会出现服务下线,那么消费者就会拿到一个无效的服务,请求会失败,那我们需要对消费者服务做一些重试,或在熔断策略。
  • 当EurekaServer开启自我保护时,监控主界面会出现红色警告信息,我们可以使用eureka.server.enable-self-preservation=false来关闭EurekaServer的保护机制,这样可以确保注册中心中不可用的实例被及时的剔除,但是不推荐

5、EurekaClient实例

  • 参考文档: https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__service_discovery_eureka_clients.html#netflix-eureka-client-starter
  • service-user-server-31000 与 service-order-server-21000 两个都是EurekaClient客户端,都需要去集成EurekaClient,。

(1)service-user-server-31000–用户服务

a.service-user-server-31000 项目结构

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

b.在pom.xml文件,引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud-parent</artifactId>
        <groupId>com.lfg</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-user-31000</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-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 #实例ID
    prefer-ip-address: true #开启,使用指定ip进行注册
e.启动测试

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

(2)service-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/eureka
  instance:
    prefer-ip-address: true #启动ip注册 默认使用计算机的名字注册
    instance-id: service-order:21000

五、RestTemplate 服务通信

1、服务通信流程,以订单服务通信用户服务为例

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

  • 调用关系:浏览器—>订单服务—>用户服务
  • 订单服务通过RestTemplate向用户服务发起调用,目的是要获取到用户服务返回的User对象,最终是需要浏览器获取到User。

2、RestTemplate介绍

  • 微服务的通信协议主流的有RPC,Http,SpringCloud是基于Http Restful 风格 ,在Java中发起一个Http请求的方式很多,比如 Apache的HttpClient , OKHttp等等 。
  • Spring为我们封装了一个基于Restful的使用非常简单的Http客户端工具 RestTemplate ,我们就用它来实订单服务和用户服务的通信。
  • 需要注意的是,RestTmplate本身不具备服务发现和负载均衡器的功能,案例只是演示在订单服务中使用RestTemplate基于ip和端口的方式向用户服务发起调用,即:不走注册中心,不使用服务发现方式。

3、编码实现RestTemplate

(1)搭建公共模块–service-entity

  • 该模块用户存放实体类
a.service-entity 项目结构

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

b.在pom.xml文件中引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud-parent</artifactId>
        <groupId>com.lfg</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-entity</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
c.创建实体类
  • 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模块
<dependency>
    <groupId>com.lfg</groupId>
    <artifactId>service-entity</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
e.在用户模块的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/1
    @GetMapping("/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();
    }

    /*@Bean
    public 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 {

    @Autowired
    private 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.测试

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

六、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请求实现服务的调用。

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

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:31001
    prefer-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 #实例ID
    prefer-ip-address: true #开启,使用指定ip进行注册
#端口号
server:
  port: 31000
#指定服务的名字
spring:
  application:
    name: service-user

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

5、消费者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中引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

(2)开启负载均衡

  • @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客户端 工具
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    /*@Bean
    public 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 {

    @Autowired
    private 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、测试

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

七、Ribbon负载均衡算法

1、Ribbon内置算法

SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法,微服务,spring cloud,负载均衡,spring

2、配置负载均衡算法

(1)注解全局配置

/**
 * 订单的启动类
 */
@SpringBootApplication
@EnableEurekaClient
public class OrderServerApplication1030
{

    //配置一个RestTemplate ,Spring封装的一个机遇Restful风格的http客户端 工具
    //@LoadBalanced :让RestTemplate有负载均衡的功能
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    //负载均衡算法
    @Bean
    public RandomRule randomRule(){
        return new RandomRule();
    }
    //省略...

(3)yml方式配置负载均衡算法

a.配置全局Ribbon算法
ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
b.配置某个服务的Ribbon算法
service-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

八、Ribbon调优配置

1、超时配置

  • 使用Ribbon进行服务通信时为了防止网络波动造成服务调用超时,我们可以针对Ribbon配置超时时间以及重试机制

  • 也可以针对具体的服务进行超时配置:如"<服务名>.ribbon…"文章来源地址https://www.toymoban.com/news/detail-635697.html

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 #针对于哪些服务需要饥饿加载

``

(3)yml方式配置负载均衡算法

a.配置全局Ribbon算法
ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
b.配置某个服务的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 #针对于哪些服务需要饥饿加载

到了这里,关于SpringCloud入门Day01-服务注册与发现、服务通信、负载均衡与算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springcloud Eureka服务注册与发现

    代码上传到 :https://github.com/13thm/study_springcloud/tree/main/days3 什么是服务治理 Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理 什么是服务注册与发现 Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使

    2024年01月18日
    浏览(69)
  • 什么是SpringCloud Eureka服务注册与发现

    😀前言 本篇博文是关于SpringCloud Eureka 介绍,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉 💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰 如果文

    2024年02月09日
    浏览(49)
  • SpringCloud服务注册与发现组件Eureka(五)

    Eureka github 地址: https://github.com/Netflix/eureka Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功

    2024年02月09日
    浏览(64)
  • 【SpringCloud微服务】- Eureka服务注册与服务发现Discovery

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。 Eureka包含两个组件: Eureka Server 和 E

    2024年02月03日
    浏览(53)
  • 【SpringCloud】Eureka原理分析、搭建Eureka服务、服务注册、服务发现

    🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 当有两个服务,第一个服务需要远程调用第二个服务,采用的方式是发起一次HTTP请求,在之前的代码中是将服务提供者的ip和端口号硬编码到

    2024年02月07日
    浏览(50)
  • SpringCloud_Eureka服务的注册与发现

    分布式:分布式解决的是系统性能问题: 即 解决系统部署上单点的问题 ,尽量让组成系统的子系统分散在不同的机器上进而提高系统的吞吐能力。 即多个相同的子系统在不同的服务器上。 分布式系统架构存在问题通过服务治理解决。 微服务:将系统的业务功能划分为极小

    2023年04月22日
    浏览(51)
  • SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)

    一、spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring cloud是基于springboot的,所以需

    2024年02月11日
    浏览(50)
  • Go gRPC etcd实现服务注册发现与负载均衡

    如果不了解go + grpc 调用方式和实现细节,可以参考上一篇文章 golang grpc配置使用实战教程 技术点 版本 描述 golang 1.19 基础版本 grpc v1.41.0 gRPC golang包 etcd server 3.5.0 注册中心 etcd client v3.5.8 客户端服务发现和负载均衡 服务注册依赖etcd的 key-value操作,key作为gRPC服务唯一标识,

    2024年02月05日
    浏览(58)
  • Nacos服务注册或发现、Nacos服务分级模型、Nacos负载均衡策略、加权负载均衡、Nacos环境隔离

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

    2024年01月16日
    浏览(40)
  • SpringCloud微服务 【实用篇】| Eureka注册中心、Ribbon负载均衡

    目录 一:Eureka注册中心 1. Eureka原理 2. 动手实践 ①搭建EurekaServer ②服务注册 ③服务发现  二:Ribbon负载均衡 1. 负载均衡原理 2. 负载均衡策略 3. 懒加载 tips:前些天突然发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家,感兴趣的同学可以

    2024年02月05日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包