天天看點

springcloud+eureka+ribbon多服務負載均衡(2)

這一次,我們的服務方有兩個(8888,9999),然後都注冊到eureka上,但是要注意是注冊使用同一個服務名稱,消費方可以通過ribbon,根據指定的負載均衡算法通路到服務方。

所有服務如下圖:

springcloud+eureka+ribbon多服務負載均衡(2)

1eureka注冊中心 microservicecloud-Eureka-7001

springcloud+eureka+ribbon多服務負載均衡(2)

pom.xml

<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>
  <parent>
    <groupId>com.wuk.springcloud</groupId>
    <artifactId>microservicecloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>microservicecloud-Eureka-7001</artifactId>
  <dependencies>
   <!--eureka-server服務端 -->
   <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-eureka-server</artifactId>
   </dependency>
   <!-- 修改後立即生效,熱部署 -->
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>springloaded</artifactId>
   </dependency>
   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-devtools</artifactId>
   </dependency>
  </dependencies>
</project>
           

application.yml

server:
  port: 7001

eureka:
  instance:
    hostname: localhost  #eureka服務端的執行個體名稱
  client:
    register-with-eureka: false   #false表示不向注冊中心注冊自己。
    fetch-registry: false #false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要去檢索服務
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/    #設定與Eureka Server互動的位址查詢服務和注冊服務都需要依賴這個位址。
           

EurekaServer7001_App.java

package com.wuk;

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

@SpringBootApplication
@EnableEurekaServer //EurekaServer伺服器端啟動類,接受其它微服務注冊進來
public class EurekaServer7001_App {

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

}

           

2 服務方8888 microservicecloud-dept-8888

它有單獨的資料庫

springcloud+eureka+ribbon多服務負載均衡(2)

它的資料庫

springcloud+eureka+ribbon多服務負載均衡(2)

pom.xml

<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>
	<parent>
		<groupId>com.wuk.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>microservicecloud-dept-8888</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.wuk.springcloud</groupId>
			<artifactId>microservicecloud-api</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<!-- 修改後立即生效,熱部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- 将微服務provider側注冊進eureka -->
	   <dependency>
	     <groupId>org.springframework.cloud</groupId>
	     <artifactId>spring-cloud-starter-eureka</artifactId>
	   </dependency>
	   <dependency>
	     <groupId>org.springframework.cloud</groupId>
	     <artifactId>spring-cloud-starter-config</artifactId>
	   </dependency>
	</dependencies>
</project>
           

application.yml

要注意的地方就是兩個服務要注冊到一個服務名上

server:
  port: 8888
  
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置檔案所在路徑
  type-aliases-package: com.wuk.entity    # 所有Entity别名類所在包
  mapper-locations: 
  - classpath:mybatis/mapper/**/*.xml
   
spring:
   application:
    name: producers    #注冊在eureka上的服務名稱,後續消費方通路要用它,如果多個服務負載均衡,就要保持一緻
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 目前資料源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://127.0.0.1:3306/cloudDB01              # 資料庫名稱
    username: root
    password: 123456
    dbcp2:
      min-idle: 5                                           # 資料庫連接配接池的最小維持連接配接數
      initial-size: 5                                       # 初始化連接配接數
      max-total: 5                                          # 最大連接配接數
      max-wait-millis: 200                                  # 等待連接配接擷取的最大逾時時間
      
eureka:
  client: #用戶端注冊進eureka服務清單内
    service-url: 
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: microservicecloud-dept-8888  #自定義服務名稱  
    prefer-ip-address: true   #顯示服務ip


           

其他的檔案上一篇有,不做贅述。

3 服務9999 microservicecloud-dept-9999

springcloud+eureka+ribbon多服務負載均衡(2)

資料庫如下:

springcloud+eureka+ribbon多服務負載均衡(2)

pom.xml

<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>
  <parent>
    <groupId>com.wuk.springcloud</groupId>
    <artifactId>microservicecloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>microservicecloud-dept-9999</artifactId>
  <dependencies>
		<dependency>
			<groupId>com.wuk.springcloud</groupId>
			<artifactId>microservicecloud-api</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jetty</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<!-- 修改後立即生效,熱部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
		<!-- 将微服務provider注冊進eureka -->
	   <dependency>
	     <groupId>org.springframework.cloud</groupId>
	     <artifactId>spring-cloud-starter-eureka</artifactId>
	   </dependency>
	   <dependency>
	     <groupId>org.springframework.cloud</groupId>
	     <artifactId>spring-cloud-starter-config</artifactId>
	   </dependency>
	</dependencies>
</project>
           

application.yml

server:
  port: 9999
  
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml        # mybatis配置檔案所在路徑
  type-aliases-package: com.wuk.entity    # 所有Entity别名類所在包
  mapper-locations: 
  - classpath:mybatis/mapper/**/*.xml
   
spring:
   application:
    name: producers  #注冊在eureka上的服務名稱,後續消費方通路要用它,如果多個服務負載均衡,就要保持一緻
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 目前資料源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://127.0.0.1:3306/cloudDB02              # 資料庫名稱
    username: root
    password: 123456
    dbcp2:
      min-idle: 5                                           # 資料庫連接配接池的最小維持連接配接數
      initial-size: 5                                       # 初始化連接配接數
      max-total: 5                                          # 最大連接配接數
      max-wait-millis: 200                                  # 等待連接配接擷取的最大逾時時間
      
eureka:
  client: #用戶端注冊進eureka服務清單内
    service-url: 
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: microservicecloud-dept-9999  #自定義服務名稱  
    prefer-ip-address: true   #顯示服務ip


           

4 消費方 microservicecloud-consumer-dept-80

springcloud+eureka+ribbon多服務負載均衡(2)

ConfigBean.java

注意這裡ribbon提供的幾個負載均衡算法

算法有:

  1. RoundRobinRule()輪詢
  2. RandomRule()随機
  3. AvailabilityFilteringRule()先輪詢,過濾掉故障服務,然後再按照輪詢方式
  4. WeightedResponseTimeRule()在最開始先輪詢,然後統計響應時間,等到資料足夠,計算出權重,然後切換到該算法,響應時間短的容易被選中
  5. RetryRule() 先輪詢,如果服務失敗,然後在指定時間内進行重試,擷取可用服務
  6. BestAvailableRule()先過濾掉由于多次通路故障而處于斷路或者跳閘的服務,然後選擇一個并發量小的服務
package com.wuk.cfgbeans;

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;

import com.netflix.loadbalancer.AvailabilityFilteringRule;
import com.netflix.loadbalancer.BestAvailableRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RetryRule;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.WeightedResponseTimeRule;


@Configuration
public class ConfigBean {
	/**
	 * RestTemplate提供了多種便捷通路遠端Http服務的方法, 
		是一種簡單便捷的通路restful服務模闆類,是Spring提供的用于通路Rest服務的用戶端模闆工具集

	 * @return
	 */
	@LoadBalanced
	@Bean
	public RestTemplate getRestTemplate() {
		return new RestTemplate();
	}

	@Bean
	public IRule myRule() {
		
		//RoundRobinRule()輪詢
		//RandomRule()随機
		//AvailabilityFilteringRule()先輪詢,過濾掉故障服務,然後再按照輪詢方式
		//WeightedResponseTimeRule()在最開始先輪詢,然後統計響應時間,等到資料足夠,計算出權重,然後切換到該算法,響應時間短的容易被選中
		//RetryRule() 先輪詢,如果服務失敗,然後在指定時間内進行重試,擷取可用服務
		//BestAvailableRule()先過濾掉由于多次通路故障而處于斷路或者跳閘的服務,然後選擇一個并發量小的服務
		return new RandomRule();
	}
}

           

DeptController_Consumer.java

package com.wuk.controller;

import java.util.List;

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

import com.wuk.entity.Dept;

@RestController
public class DeptController_Consumer {
	//之前我們采用的是ip+端口,現在直接采用服務名
	private static final String REST_URL_PREFIX = "http://producers";

	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping(value = "/consumer/dept/add")
	public boolean add(Dept dept) {
		return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
	}
	
	@RequestMapping(value = "/consumer/dept/get/{id}")
	public Dept get(@PathVariable("id") Long id) {
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/consumer/dept/list")
	public List<Dept> list() {
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
	}
}

           

CusumerDeptApplication.java

package com.wuk;

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

@SpringBootApplication
@EnableEurekaClient
public class CusumerDeptApplication {

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

           

繼續閱讀