Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试

一、spring cloud介绍

spring cloud 是一系列框架的集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 spring boot 的开发风格做到一键启动和部署。spring cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 spring boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

spring cloud 对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用 spring cloud 一站式解决方案能在从容应对业务发展的同时大大减少开发成本。同时,随着近几年微服务架构和 docker 容器概念的火爆,也会让 spring cloud 在未来越来越“云”化的软件开发风格中立有一席之地,尤其是在目前五花八门的分布式解决方案中提供了标准化的、一站式的技术方案,意义可能会堪比当年 servlet 规范的诞生,有效推进服务端软件系统技术水平的进步。

1、Spring cloud是一个工具集,集成了多种工具,来解决服务中的各种问题。
微服务的整体解决方案,微服务全家桶
服务发现、远程调用、负载均衡、系统容错—降级熔断、API网关、配置中心、系统监控。。。
2、不是一个解决单一问题的框架

二、spring cloud技术组成

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第1张图片

1、eureka

微服务治理,服务注册和发现

2、ribbon

负载均衡、请求重试

3、hystrix

断路器,服务降级、熔断

4、feign

ribbon + hystrix 集成,并提供声明式客户端

5、hystrix dashboard 和 turbine

hystrix 数据监控

6、zuul

API 网关,提供微服务的统一入口,并提供统一的权限验证

7、config

配置中心

8、bus

消息总线, 配置刷新

9、sleuth+zipkin

链路跟踪

三、Spring Cloud对比Dubbo

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第2张图片
1、Dubbo

Dubbo只是一个远程调用(RPC)框架
默认基于长连接,支持多种序列化格式

dubbo是远程调用工具—RPC调用,java序列化—效率高

2、Spring Cloud --大多是企业的选择

框架集
提供了一整套微服务解决方案(全家桶)
基于http调用, Rest API

Spring cloud集成工具,集成多种工具解决微服务中的所有问题----Http,RestAPI调用,http请求

四、开发环境

IDEA/STS、Lombok、Maven—依赖有问题,可通过阿里/中央仓库来回切换,尝试更新

Spring MVC接收参数的几个注解:

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第3张图片

五、eureka注册中心

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第4张图片

1、作用:服务注册和发现

服务注册:
(1)提供者:provider----向注册中心注册自己的地址
(2)消费者:consumer----从注册中心发现其他服务

2、运行机制:注册、拉取、心跳、自我保护模式

(1)注册:一次次反复链接,知道注册成功为止
(2)拉取:每个30秒拉取一次注册表,来更新注册信息
(3)心跳:每30秒发送一次心跳(提供者发送),3次收不到则删除父
(4)自我保护模式:特殊情况:由于网络不稳定,15分钟内,85%服务器出现心跳异常----丢失一次,保护所有注册信息不被删除,3次丢失也不删除,网络恢复后,自动退出保护模式,在开发测试期间,可关闭保护模式。

3、搭建eureka服务

zk—线程的应用
eureka—需要手动添加依赖:eureka server

3.1、添加eureka server依赖

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

3.2、配置YML文件

1、关闭保护模式
2、配置主机名(集群中区分服务器)
3、单台服务器:不向自己注册,也不向自己拉取

eureka:
  # 1、关闭保护模式
  server:
    enable-self-preservation: false
  # 2、主机名、配置集群时用来区分主机名
  instance:
    hostname: eureka1
  # 3、单台配置,不向自己注册,也不从自己拉取
  client:
    register-with-eureka: false
    fetch-registry: false

eureka 集群服务器之间,通过 hostname 来区分

eureka.server.enable-self-preservation

eureka 的自我保护状态:心跳失败的比例,在15分钟内是否超过85%,如果出现了超过的情况,Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务

eureka.client.register-with-eureka=false

不向自身注册

eureka.client.fetch-registry=false

不从自身拉取注册信息

eureka.instance.lease-expiration-duration-in-seconds

最后一次心跳后,间隔多久认定微服务不可用,默认90

3.3、启动类,主程序:添加 @EnableEurekaServer

package cn.tedu.sp05;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class Sp05EurekaApplication {
	public static void main(String[] args) {
		SpringApplication.run(Sp05EurekaApplication.class, args);
	}
}

3.4、修改 hosts 文件,添加 eureka 域名映射

C:\Windows\System32\drivers\etc\hosts
添加内容:

127.0.0.1       eureka1
127.0.0.1       eureka2

启动,并访问测试
http://eureka1:2001
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第5张图片

源码: https://github.com/benwang6/spring-cloud-repo

4、eureka和zookeeper的区别

  • eureka:AP,强调可用性;集群—>对等结构,无主从结构之分
  • zookeeper:CP,强调一致性;集群—>主从结构,会出现服务中断的问题

五、eureka和服务提供者(service provider)

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第6张图片
配置

1、添加eureka client依赖 – Eureka Discovery Client

在pom.xml文件中添加eureka客户端依赖

在pom文件中使用快捷键:Alt+Insert—>Edit Starters
若没有,则添加插件EditStarters

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第7张图片

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第8张图片

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、在yml文件中配置eureka连接地址

# defaultZone:默认地址,其他地点配置,需要由云服务来提供
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka

3、添加@EnableDiscoveryClient(可选)

eureka.instance.lease-renewal-interval-in-seconds
心跳间隔时间,默认 30 秒

defaultZone,默认位置,可以修改为具体地理位置,比如:beiJing, shangHai, shenZhen 等,表示 eureka 服务器的部署位置, 需要云服务器提供

eureka.client.registry-fetch-interval-seconds
拉取注册信息间隔时间,默认 30 秒

主程序启用服务注册发现客户端
修改 item-service、user-service 和 order-service,
主程序添加 @EnableDiscoveryClient 注解

启动并访问eureka查看注册信息

  • http://eureka1:2001
    Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第9张图片

源码: https://github.com/benwang6/spring-cloud-repo

4、报错:clientHandlerException::861连接超时

原因:自动配置的集群服务器:localhost:8761
解决:在yml文件中添加配置:

service-url:
 defaultZone:http://eureka1:2001/eureka

六、eureka和服务提供者的高可用

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第10张图片
item-service 高可用
启动参数--server.port 可以覆盖yml中的端口配置

配置启动参数:

--server.port=8001

编辑启动配置:
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第11张图片
编辑第二个提供者:

--server.port=8002

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第12张图片
启动测试:
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第13张图片

  • 访问两个端口测试
    http://localhost:8001/35
    http://localhost:8002/35

1、ureka 高可用

相同配置:profiles的配置会覆盖主配置
添加两个服务器的 profile 配置文件

1、application-eureka1.yml

eureka:
  instance:
    hostname: eureka1
  client:
    register-with-eureka: true  #profile的配置会覆盖公用配置
    fetch-registry: true        #profile的配置会覆盖公用配置
    service-url: 
      defaultZone: http://eureka2:2002/eureka  #eureka1启动时向eureka2注册

2、application-eureka2.yml

eureka:
  instance:
    hostname: eureka2
  client:
    register-with-eureka: true  #profile的配置会覆盖公用配置
    fetch-registry: true        #profile的配置会覆盖公用配置
    service-url: 
      defaultZone: http://eureka1:2001/eureka  #eureka2启动时向eureka1注册

2、配置启动参数 --spring.profiles.active--server.port

  • eureka1 启动参数:
--spring.profiles.active=eureka1 --server.port=2001

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第14张图片

  • eureka2 启动参数:
--spring.profiles.active=eureka2 --server.port=2002

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第15张图片

如果在命令行运行,可以在命令行中添加参数:
java -jar xxx.jar --spring.profiles.active=eureka1 --server.port=2001
java -jar xxx.jar只加载主配置

3、访问 eureka 服务器,查看注册信息

  • http://eureka1:2001/

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第16张图片

  • http://eureka1:2002/

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第17张图片
eureka客户端注册时,向两个服务器注册
修改以下微服务
sp02-itemservice
sp03-userservice
sp04-orderservice

eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

当一个 eureka 服务宕机时,仍可以连接另一个 eureka 服务
源码: https://github.com/benwang6/spring-cloud-repo

七、ribbon 服务消费者

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第18张图片
ribbon 提供了负载均衡和重试功能, 它底层是使用 RestTemplate 进行 Rest api 调用

1、RestTemplate

RestTemplate 是SpringBoot提供的一个Rest远程调用工具,类似HttpClient,对Http Rest API
调用做了高度封装,只需要调用一个方法就可以完成请求、响应、json转换
常用方法:

  • getForObject(url,转换的类型.class,提交的参数数据) - 执行get请求
  • postForObject(url,提交的协议体数据,转换的类型.class) - 执行post请求

之前的系统结构是浏览器直接访问后台服务
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第19张图片

后面我们通过一个Demo项目演示 Spring Cloud 远程调用
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第20张图片
主程序:
创建 RestTemplate 实例
RestTemplate 是用来调用其他微服务的工具类,封装了远程调用代码,提供了一组用于远程调用的模板方法,例如:getForObject()、postForObject() 等

package cn.tedu.sp06;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class Sp06RibbonApplication {
	
	//创建 RestTemplate 实例,并存入 spring 容器
	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

	public static void main(String[] args) {
		SpringApplication.run(Sp06RibbonApplication.class, args);
	}
}

2、ribbon

SpringCloud提供的工具,对RestTemplate进行了封装,提供了负载均衡和重试的功能。

八、ribbon 负载均衡和重试

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第21张图片
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第22张图片

1、Ribbon 负载均衡

  • 1、从eureka获得地址值
  • 2、使用多个地址来回调用
  • 3、拿到一个地址,抵用restTemplate执行远程调用

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第23张图片

添加负载均衡

  • 1、添加ribbon依赖(eureka client中已经包含,无需单独添加)
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
  • 2、添加@LoadBalanced注解对restTemplate记性增强
    @LoadBalanced 负载均衡注解,会对 RestTemplate 实例进行封装,创建动态代理对象,并切入(AOP)负载均衡代码,把请求分发到集群中的服务器

  • 3、用restTemplate调用的地址改成service-id(注册中心注册的服务名):http://item-service/{1}

2、ribbon 重试

Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第24张图片
Spring Cloud微服务、eureka注册中心、ribbon负载均衡和重试_第25张图片
一种容错方式,调用远程服务失败(异常、超时)时,可以自动进行重试调用

添加重试:

1、在pom.xml文件中添加 spring-retry 依赖

<dependency>
	<groupId>org.springframework.retry</groupId>
	<artifactId>spring-retry</artifactId>
</dependency>

application.yml 配置 ribbon 重试

spring:
  application:
    name: ribbon
    
server:
  port: 3001
  
eureka:
  client:    
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
      
ribbon:
  MaxAutoRetriesNextServer: 2
  MaxAutoRetries: 1
  OkToRetryOnAllOperations: true

2、配置重试参数:

(1)MaxAutoRtries - 单台服务器的重试次数

(2)MaxAutoRtriesNextServer - 更换服务器的次数

(3)OkToRetryOnAllOperations - 是否对所有类型请求都进行重试,默认只对get重试

(4)ConnectTimeout - 和远程服务建立连接的等待超时时长

(5)ReadTimeout - 建立连接并发送请求后,等待响应的超时时长

两个超时设置,不能在yml中配置,而是要在java代码中设置

  • ConnectionTimeout
  • ReadTimeout
  • OkToRetryOnAllOperations=true
    默认只对GET请求重试, 当设置为true时, 对POST等所有类型请求都重试
  • MaxAutoRetriesNextServer
    更换实例的次数
  • MaxAutoRetries
    当前实例重试次数,尝试失败会更换下一个实例

主程序设置 RestTemplate 的请求工厂的超时属性

package cn.tedu.sp06;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class Sp06RibbonApplication {

	@LoadBalanced
	@Bean
	public RestTemplate getRestTemplate() {
		SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
		f.setConnectTimeout(1000);
		f.setReadTimeout(1000);
		return new RestTemplate(f);
		//RestTemplate 中默认的 Factory 实例中,两个超时属性默认是 -1,
		//未启用超时,也不会触发重试
		//return new RestTemplate();
	}
	public static void main(String[] args) {
		SpringApplication.run(Sp06RibbonApplication.class, args);
	}
}
  • ribbon的重试机制,在 feign 和 zuul 中进一步进行了封装,后续可以使用feign或zuul的重试机制

源码: https://github.com/benwang6/spring-cloud-repo

你可能感兴趣的:(Java,1024程序员节,java,eureka,ribbon)