欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringCloud核心组件

程序员文章站 2022-03-14 09:47:59
...

一、Eureka

1、Eureka采用了C/S的设计架构。Eureka Server作为服务注册工程的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳链接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。SpringCloud的一些其他模块(比如Zuul)就可以通过Eureka Server来发现系统中的其他微服务,并执行相关的逻辑。
SpringCloud核心组件
 
Eureka包含两个组件:Eureka Server和Eureka Client
 
Eureka Server提供服务注册服务
各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中看到。
 
Eureka Client是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eurkea Server将会从服务注册表中把这个服务节点移除(默认90秒)。

二、Ribbon负载均衡

1、SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
 
2、Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项,如:连接超时、重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。SpringCloud的负载均衡算法可以自定义
 
3、LB:即负载均衡,分为集中式LB和进程内LB
  (1)集中式LB:即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5(超级贵),也可以是软件,如nginx),由改设施负责把访问请求通过某种策略转发至服务的提供方,偏向于硬件
  (2)进程内LB:将LB逻辑集成到消费方,消费从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
 
  Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过他来获取到服务提供方的地址。
 
项目演示
1、首先导入pom文件(客户端的子工程)

		<!-- Ribbon相关三个 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-ribbon</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>

 
2、修改application配置文件

eureka:
  client:
    register-with-eureka: false	//自己不注册
    service-url: 
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  

 
3、在ConfigBean添加新注解@LoadBalanced,获得Rest时加入Ribbon的配置

@Configuration
public class ConfigBean //boot -->spring   applicationContext.xml --- @Configuration配置   ConfigBean = applicationContext.xml
{ 
	@Bean
	@LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端       负载均衡的工具。
	public RestTemplate getRestTemplate()
	{
		return new RestTemplate();
	}
	
	@Bean
	public IRule myRule()
	{
		//return new RoundRobinRule();
		//return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
		return new RetryRule();
	}
}

 
4、在启动类加上@EnableEurekaClient
 
5、修改客户端类的微服务名字

private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

 
负载均衡演示(Ribbon,默认轮询算法)
1、创建余下的子工程
SpringCloud核心组件
 
2、修改配置文件,以8001为例,这里需要改端口、数据库名、Eureka别名

server:
  port: 8001
  
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置文件所在路径
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包
  mapper-locations:
  - classpath:mybatis/mapper/**/*.xml                       # mapper映射文件
    
spring:
   application:
    name: microservicecloud-dept 
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/cloudDB01              # 数据库名称
    username: root
    password: root
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                  # 等待连接获取的最大超时时间
      
eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      #defaultZone: http://localhost:7001/eureka
       defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/      
  #Eureka页面微服务的名字(别名)
  instance:
    instance-id: microservicecloud-dept8001
    prefer-ip-address: true     #访问路径可以显示IP地址(内网坏境的ip地址)

 #关于微服务的描述
info: 
  app.name: atguigu-microservicecloud
  company.name: www.atguigu.com
  #这里不写死,灵活调用
  build.artifactId: $project.artifactId$
  build.version: $project.version$

 
负载均衡算法(IRule),七个。
RetryRule():如果多个服务在运行中,突然有一个服务故障,那么它将继续执行,直到发现该服务确实不能访问了,那么才跳过该服务,重新轮询。

//其他算法,不定义该方法,默认轮询算法
	@Bean
	public IRule myRule()
	{
		//return new RoundRobinRule();	//轮询算法
		//return new RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。
		return new RetryRule();
	}

 
自定义IRule,这里写一个让每个微服务都访问五次,在跳到下一个微服务的算法
1、在启动类加上注解,注意:这个自定义配置类不能放在@ComponenScan所扫描的当前包下以及子包下,否则自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说达不到我们想要的目的

@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)

 
2、创建自定义IRule配置类
SpringCloud核心组件

@Configuration
public class MySelfRule
{
	@Bean
	public IRule myRule() {
		//return new RandomRule();// Ribbon默认是轮询,我自定义为随机
		//return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机
		
		return new RandomRule_ZY();// 我自定义为每台机器5次,这里返回我们自定义的IRule类
	}
}
public class RandomRule_ZY extends AbstractLoadBalancerRule
{

	// total = 0 // 当total==5以后,我们指针才能往下走,
	// index = 0 // 当前对外提供服务的服务器地址,
	// total需要重新置为零,但是已经达到过一个5次,我们的index = 1
	// 分析:我们5次,但是微服务只有8001 8002 8003 三台,OK?
	// 
	
	
	private int total = 0; 			// 总共被调用的次数,目前要求每台被调用5次
	private int currentIndex = 0;	// 当前提供服务的机器号

	public Server choose(ILoadBalancer lb, Object key) {
		if (lb == null) {
			return null;
		}
		Server server = null;

		while (server == null) {
			if (Thread.interrupted()) {
				return null;
			}
			List<Server> upList = lb.getReachableServers();
			List<Server> allList = lb.getAllServers();

			int serverCount = allList.size();
			if (serverCount == 0) {
				/*
				 * No servers. End regardless of pass, because subsequent passes only get more
				 * restrictive.
				 */
				return null;
			}

//			int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
//			server = upList.get(index);

			
//			private int total = 0; 			// 总共被调用的次数,目前要求每台被调用5次
//			private int currentIndex = 0;	// 当前提供服务的机器号
            if(total < 5) {
	            server = upList.get(currentIndex);
	            total++;
            }else {
	            total = 0;
	            currentIndex++;
	            if(currentIndex >= upList.size()) {
	              currentIndex = 0;
	            }
            }			
			
			
			if (server == null) {
				/*
				 * The only time this should happen is if the server list were somehow trimmed.
				 * This is a transient condition. Retry after yielding.
				 */
				Thread.yield();
				continue;
			}

			if (server.isAlive()) {
				return (server);
			}

			// Shouldn't actually happen.. but must be transient or a bug.
			server = null;
			Thread.yield();
		}

		return server;

	}

	@Override
	public Server choose(Object key)
	{
		return choose(getLoadBalancer(), key);
	}

	@Override
	public void initWithNiwsConfig(IClientConfig clientConfig)
	{
		// TODO Auto-generated method stub

	}

}
相关标签: SpringCloud