SpringCloud study notes 2-- service registration and discovery, @ LoadBalanced load balancing, pure handwriting Ribbon for local load balancing

A, SpringCloud Profile

        Is based on micro-services framework SpringBoot basis of development, SpringCloud solution framework is a very complete micro-current service, its contents include service management, registry, configuration management, circuit breakers, intelligent routing, micro broker, a control bus, global lock, distributed session and so on.

      SpringCloud contains a number of sub-projects:

         1) SpringCloud config distributed configuration center.

         2) SpringCloud netfix core components.

         3) Eureka: service governance registry.

         4) Hystrix: Service protection framework, circuit breakers, for system security. Service degradation, current limiting, fuse.

         5) Ribbon: client load balancer.

         6) Feign: declarative services and Hystrix calling component based on the Ribbon.

         7) Zuul: Gateway component that provides intelligent routing, access filtering.

Two, SpringCloud principles of service registration and discovery

   1, RPC remote invocation framework core design ideas

                That the registration center, since the use of a registry dependencies between each service and service management (service governance concept).

   2. What is a Service Management

                 In the traditional framework of remote RPC call, the dependencies between each service and service management more complex. This service can be used when treatment technology, management dependencies between services and each service can be local load balancing, to achieve service discovery and registration, fault tolerance and so on.

   3, the principle of service registration and discovery

   (Springcloud in supports three registry: Consul (go language), Eureka, Zookeeper)

     Service Registration: The registration service information to the registry;

     Service discovery: For service information from the registry.

                1)启动注册中心:在任何RPC远程框架中,都会有一个注册中心(专门存放服务地址相关信息)。

                2)服务提供者在启动的时候,会把当前服务基本信息(服务地址、端口)以别名方式注册到注册中心。

                3)消费者在调用接口的时候,使用服务别名也就是去注册中心上获取实际rpc远程调用地址。

                4)消费者获取实际rpc远程调用地址之后,再使用本地httpclient技术实现调用。

三、SpringCloud使用Eureka作为注册中心(默认情况下每隔30秒更新一次服务调用地址)

建立Eureka注册中心

     1、建立maven项目,导入相关jar包

<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.gonghua</groupId>
  <artifactId>springcloud-eureka-server</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <parent>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-parent</artifactId>
  	<version>2.0.1.RELEASE</version>
  </parent>
  
  <!-- 管理依赖 -->
  <dependencyManagement>
  		<dependencies>
  			<dependency>
  				<groupId>org.springframework.cloud</groupId>
  				<artifactId>spring-cloud-dependencies</artifactId>
  				<version>Finchley.M7</version>
  				<type>pom</type>
  				<scope>import</scope>
  			</dependency>
  		</dependencies>
  </dependencyManagement>
  <dependencies>
  	<!-- springcloud eureka-server -->
  	<dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  	</dependency>
  </dependencies>
  <!-- 注意:这里必须添加,否则各种依赖会出问题 -->
  <repositories>
  	<repository>
  		<id>spring-milestones</id>
  		<name>Spring Milestones</name>
  		<url>https://repo.spring.io/libs-milestone</url>
  		<snapshots>
  			<enabled>false</enabled>
  		</snapshots>
  	</repository>
  </repositories>
  
</project>

2、在项目的src/main/resources下建立application.yml或application.properties文件,配置相关信息。

server.port=8080
##注册中心ip地址
eureka.instance.hostname: 127.0.0.1
##注册地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
##因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要为true)
eureka.client.register-with-eureka: false
##因为自己是注册中心,不需要去检索服务信息
eureka.client.fetch-registry: false

3、建立java启动类

package com.gonghua;

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

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

}

4、浏览器地址栏输入:http://127.0.0.1:8080,如下则启动成功

 

建立服务提供者注册到Eureka上。

1、建立maven工程,在pom.xml中导入相关jar包,代码如下:

<!-- 管理依赖 -->
  <dependencyManagement>
  		<dependencies>
  			<dependency>
  				<groupId>org.springframework.cloud</groupId>
  				<artifactId>spring-cloud-dependencies</artifactId>
  				<version>Finchley.M7</version>
  				<type>pom</type>
  				<scope>import</scope>
  			</dependency>
  		</dependencies>
  </dependencyManagement>
  
  <dependencies>
  <!-- springboot整合web组件 -->
  	<dependency>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-web</artifactId>
  	</dependency>
  	<!-- springboot整合eureka客户端 -->
  	<dependency>
  		<groupId>org.springframework.cloud</groupId>
  		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  	</dependency>
  </dependencies>
  
  <!-- 注意:这里必须添加,否则各种依赖会出问题 -->
  <repositories>
  	<repository>
  		<id>spring-milestones</id>
  		<name>Spring Milestones</name>
  		<url>https://repo.spring.io/libs-milestone</url>
  		<snapshots>
  			<enabled>false</enabled>
  		</snapshots>
  	</repository>
  </repositories>

2、配置相关yml或properties配置,如下:

server.port=8000
##服务别名--服务注册到注册中心名称
spring.application.name=app-member
##当前会员服务注册到eureka服务地址
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
##需要将我的服务注册到eureka上
eureka.client.register-with-eureka=true
##需要去检索服务信息
eureka.client.fetch-registry=true

3、建立启动类和controller

(1)启动类如下:

package com.gonghua.api.controller;

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

@SpringBootApplication
@EnableEurekaClient
public class AppMember {
	
	//@EnableEurekaClient 将当前服务注册到eureka上
	public static void main(String[] args) {
		SpringApplication.run(AppMember.class, args);
	}

}


(2)controller类如下:
package com.gonghua.api.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MemberApiController {
		
	@RequestMapping("/getMember")
	public String getMember(){
		return "hello word!!!";
	}
}

4、先启动Eureka服务,在启动服务提供者服务,这时候刷新Eureka界面,可以看到注册上去的服务提供者 。如下:

拿到status的值,访问接口,效果如下:

建立服务消费者服务

1、建立mave你工程,导入jar包,建立properties文件,和建立服务提供者配置一样,除了property文件中的spring.application.name和port换一下。

2、建立相关类

(1)启动类

package com.gonghua.api.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class AppOrder {
	public static void main(String[] args) {
		SpringApplication.run(AppOrder.class, args);
	}
	
	/**
	 * 1、RestTemplate注册到spring容器中,否则运行时会出错,报找不到restTemplate。
	 * 2、如果使用rest方式以别名方式进行调用,须依赖ribbon负载均衡器@LoadBalanced。
	 * 	这样就能让这个RestTemplate在请求时拥有客户端负载均衡的能力
	 * @return
	 */
	@Bean
	@LoadBalanced
	RestTemplate restTemplate(){
		return new RestTemplate();
	}
	

}





(2)controller类

package com.gonghua.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class OrderController {
	//RestTemplate 是由springboot web组件提供,默认整合ribbon负载均衡器,rest方式底层是采用httpclient技术
	@Autowired
	private RestTemplate restTemplate;
	
	/**
	 * 在springcloud中有两种方式调用
	 * 1、rest调用
	 * 2、fegin(springcloud)
	 * @return
	 */
	@RequestMapping("/getOrder")
	public String getOrder(){
		//两种方式,一种是采用服务别名方式调用,一种是直接调用
		//直接调用
//		String result = restTemplate.getForObject("http://localhost:8000/getMember", String.class);
//		System.out.println("order 直接调用 member 服务:"+result);
	
		//别名调用
		String url = "http://app-member/getMember";
		String result1 = restTemplate.getForObject(url, String.class);
		System.out.println("order 别名调用 member 服务:"+result1);
		return result1;
	}

}

使用@LoadBalanced实现内部负载均衡

          服务提供者,先以端口为8000启动一变;在不停服务的情况下,更改端口为8010,在controller中加入读取端口的代码,再进行重启,这个时候就有8000和8010端口的两台服务提供者。这个时候访问就会有默认的轮询策略的负载均衡效果。如下:

controller中的代码:

package com.gonghua.api.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MemberApiController {
		
	@Value("${server.port}")
	private String serverPort;
	
	@RequestMapping("/getMember")
	public String getMember(){
		return "hello word!!!,this is my port:"+serverPort;
	}
}

效果图如下:

纯手写Ribbon实现本地负载均衡

代码如下,效果和@LoadBalanced实现的本地负载均衡一样效果

package com.gonghua.api.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * 纯手写Ribbon本地负载均衡
 * 
 * @author gh
 *
 */
@RestController
public class ExtRibbonController {
	
	//可以获取注册中心上的服务列表
	@Autowired
	private DiscoveryClient discoveryClient;
	
	//需要注释掉启动类中的@LoadBalanced注解
	@Autowired
	private RestTemplate restTemplate;
	
	//接口请求总数
	private  int reqCount = 1;
	
	@RequestMapping("/ribbonOrder")
	public String ribbonOrder(){
		//1、获取对应服务器远程调用地址
		String instanceUri = getInstance() + "/getMember";
		System.out.println("instanceUri : "+instanceUri);
		//2、可以直接使用httpclient技术实现远程调用
		String result = restTemplate.getForObject(instanceUri, String.class);
		return result;
		
	}
	
	private  String getInstance() {
		List<ServiceInstance> instances = discoveryClient.getInstances("app-member");
		if (instances == null || instances.size() <= 0 ) {
			return null;
		}
		//获取服务器集群数
		int instanceSize = instances.size();
		int serviceIndex = reqCount % instanceSize;
		reqCount++;
		return instances.get(serviceIndex).getUri().toString();
	}

}

 

发布了27 篇原创文章 · 获赞 8 · 访问量 1万+

Guess you like

Origin blog.csdn.net/gonghua0502/article/details/103240211