SpringCloud實現集羣和負載均衡

Spring cloud是一個基於Spring Boot實現的服務治理工具包,在微服務架構中用於管理和協調服務的。java

組成部分

spingcloud的五大神獸web

服務發現——Netflix Eureka算法

客服端負載均衡——Netflix Ribbon/Feignspring

服務網關——Netflix Zuulspringboot

斷路器——Netflix Hystrix服務器

分佈式配置——Spring Cloud Config架構

 

Spring cloud入門-搭建環境

1)建環境併發

       以maven多模塊化的方法搭建app

2)註冊中心負載均衡

因爲Spring Cloud爲服務治理作了一層抽象接口,因此在Spring Cloud應用中能夠支持多種不一樣的服務治理框架,好比:Netflix Eureka、Consul、Zookeeper。在Spring Cloud服務治理抽象層的做用下,咱們能夠無縫地切換服務治理實現,而且不影響任何其餘的服務註冊、服務發現、服務調用等邏輯。

3)服務提供者

4)服務消費者

 

1.1.  搭建環境pxm.xml配置

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<springboot.version>2.0.5.RELEASE</springboot.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
  1. Spring cloud入門-Eureka註冊中心

  2.  

    因爲Spring Cloud爲服務治理作了一層抽象接口,因此在Spring Cloud應用中能夠支持多種不一樣的服務治理框架,好比:Netflix Eureka、Consul、Zookeeper。在Spring Cloud服務治理抽象層的做用下,咱們能夠無縫地切換服務治理實現,而且不影響任何其餘的服務註冊、服務發現、服務調用等邏輯。

   Eureka是netflix的一個子模塊,也是核心模塊之一,Eureka是一個基於REST的服務,用於定位服務,以實現雲端中間層服務發現和故障轉移。服務註冊與發現對於微服務架構來講是很是重要的,有了    服務發現和註冊,只須要使用服務的標識符,就能夠訪問到服務,而不須要修改服務,而不須要修改服務調用的配置文件了,功能相似於dubbo的註冊中心,好比zookeeper。

  原理

 

 

三大角色:

 Eureka server提供服務註冊和發現

      Eureka Server提供服務註冊服務。各個服務提供者節點啓動後,會在Eureka Server中進行註冊,這樣Eureka server中的服務註冊表中將會存儲全部可用服務節點的信息,服務節點的信息能夠在界面中直觀的看到

Service Provider服務提供方將自身服務註冊到Eureka,從而使服務消費方可以找到。

Service Consumer服務消費方從Eureka獲取註冊服務列表,從而可以消費服務。

   Eureka client是一個java客戶端,用於簡化eureka server的交互,在應用啓動後,將會向Eureka Server發送心跳。若是Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,Eureka Server將會從服務註冊表把這個服務節點移除。

 

註冊中心的搭建

建立一個普通maven項目

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>

<!--Eureka服務端支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

  yum配置

server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
      registerWithEureka: false #是否要註冊到eureka
      fetchRegistry: false #表示是否從Eureka Server獲取註冊信息
serviceUrl:
  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #單機配置

 主類

@SpringBootApplication
@EnableEurekaServer//標識是eureka服務端
public class EnrekaServerApplication_7001 {
public static void main(String[] args) {
        SpringApplication.run(EnrekaServerApplication_7001.class);
    }
}

注意事項

自我保護引起的錯誤

 

Eureka Server 在運行期間會去統計心跳失敗比例在 15 分鐘以內是否低於 85%,若是低於 85%,Eureka Server 會將這些實例保護起來,讓這些實例不會過時,可是在保護期內若是服務恰好這個服務提供者非正常下線了,此時服務消費者就會拿到一個無效的服務實例,此時會調用失敗,對於這個問題須要服務消費者端要有一些容錯機制,如重試,斷路器等

 

搭建服務提供者

在搭建服務提供者模塊以前咱們要建立一個模塊,這個模塊是公共模塊,用來存放工共的數據

而後就是建立服務提供者,

pom.xml配置

<dependencies>
<!--公共代碼依賴-->
<dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!--springboot支持-->
<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>

<!--eureka客戶端支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

yum配置

server:
  port: 8001
spring:
  application:
     name: USER-PROVIDER #不要使用下劃線
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka #告訴服務提供者要把服務註冊到哪兒

程序主方法

@SpringBootApplication
@EnableEurekaClient //表示是eureka的客戶端
public class UserProviderApplication_8001 {
public static void main(String[] args) {
        SpringApplication.run(UserProviderApplication_8001.class);
    }
}

contrller層進行測試

@RestController
@RequestMapping("/provider")
public class UserController {

//    @Autowired
   //    private IUserService userService;
@RequestMapping("/user/{id}") //user/1
public User getUser(@PathVariable("id") Long id) {

// 正常應該調用service獲取用戶,如今模擬一下
return new User(id, "zs");
    }
}

服務消費者搭建

pom.xml配置

dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!--springboot支持-->
<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>

yml配置

server:
  port: 9001
spring:
  application:
    name: USER_CONSUMER

主程序

package cn.itsource.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

       測試

        調用服務提供者的接口

@Configuration // <beans></beans>
public class CfgBean {

@Bean //<bean class="org.springframework.web.client.RestTemplate"></bean>
public RestTemplate getRestTemplate(){
return new RestTemplate();
    }
}
@RestController
@RequestMapping("/consumer")
public class UserController {

//多個方法調用只需改一處就ok
public static  final String URL_PREFIX = "http://localhost:8001";

@Autowired
private RestTemplate restTemplate;

@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
//調用遠程服務 http請求
String url = URL_PREFIX+"/provider/user/"+id;
return restTemplate.getForObject(url,User.class );
    }
}

實現集羣

實現集羣以註冊中心爲例。咱們新建一個操做中心,操做i方法和以前的同樣,yml的配置方式變化

server:
  port: 7001
eureka:
  instance:
    hostname: eureka-7001.com
  client:
    registerWithEureka: false #是否要註冊到eureka
    fetchRegistry: false #表示是否從Eureka Server獲取註冊信息
    serviceUrl:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #單機配置
      defaultZone: http://eureka-7002.com:7002/eureka/ #集羣配置,若是有多個,有逗號分割,不要包含本身

7002: 模塊application.yml

server:
  port: 7002
eureka:
  instance:
    hostname: eureka-7002.com
  client:
    registerWithEureka: false #是否要註冊到eureka
    fetchRegistry: false #表示是否從Eureka Server獲取註冊信息
    serviceUrl:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #單機配置
      defaultZone: http://eureka-7001.com:7001/eureka/ #集羣配置,若是有多個,有逗號分割,不要包含本身

映射hosts 模擬域名解析 C:\Windows\System32\drivers\etc

127.0.0.1       eureka-7001.com

127.0.0.1       eureka-7002.com

而後就是在消費端須要注意,

把8001服務提供方代碼分別註冊到7001和7002兩個註冊中心去;完成集羣操做

server:
  port: 8001
spring:
  application:
name: user-provider #不要使用下劃線
eureka:
  client:
    service-url:
      #defaultZone: http://localhost:7001/eureka #告訴服務提供者要把服務註冊到哪兒
      defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka
instance:
  prefer-ip-address: true #顯示客戶端真實ip

負載均衡

 爲何須要負載均衡

爲了提供併發量,有時同一個服務提供者能夠部署多個。這個客戶端在調用時要根據必定的負責均衡策略完成負載調用。

1.1.  Ribbon負載均衡

Ribbon是Netflix發佈的雲中間層服務開源項目,主要功能是提供客戶端負載均衡算法。Ribbon客戶端組件提供一系列完善的配置項,如,鏈接超時,重試等。簡單的說,Ribbon是一個客戶端負載均衡器,

1.1.1.   集成原理

在服務器方配置負載均衡

咱們新建一個服務端和以前的同樣的,而後在消費端進行配置

·

<!--eureka客戶端,服務消費者也要從註冊中心獲取可用服務列表-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<!--客戶端負載均衡實現 ribbon-->
<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>

9001消費方引入ribbon

  port: 9001
eureka:
  client:
    registerWithEureka: false #不註冊到Eureka,不在註冊中心顯示
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka

主方法

@SpringBootApplication
@EnableEurekaClient
public class UserConsumerApplicaton_9001 {
public static void main(String[] args) {
        SpringApplication.run(UserConsumerApplicaton_9001.class);
    }
}

新建一個類用來獲取RestTemplate

 
 

@Configuration
public class CfgBean {

@Bean
@LoadBalanced //開啓負載均衡
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
//隨機策略
@Bean
public IRule myRule(){
return new RandomRule();//經過隨機算法分配服務端
}
}
 
@Configuration
public class CfgBean {

@Bean
 @LoadBalanced //開啓負載均衡
public RestTemplate getRestTemplate(){
return  new RestTemplate();
    }
}

@RestController
@RequestMapping("/consumer")
public class UserController {

//多個方法調用只需改一處就ok
    //public static  final String URL_PREFIX = "http://localhost:8001";
public static  final String URL_PREFIX ="http://USER-PROVIDER"; //經過服務名從註冊中心獲取服務列表,經過負載均衡調用

@Autowired
private RestTemplate restTemplate;

@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
//調用遠程服務 http請求
String url = URL_PREFIX+"/provider/user/"+id;
return restTemplate.getForObject(url,User.class );
    }
}

完後啓動就能完成負載均衡

 

 Feign負載均衡

Feign是一個聲明式的Web Service客戶端,它的目的就是讓Web Service調用更加簡單。Feign提供了HTTP請求的模板,經過編寫簡單的接口和插入註解,就能夠定義好HTTP請求的參數、格式、地址等信息。而Feign則會徹底代理HTTP請求,咱們只須要像調用方法同樣調用它就能夠完成服務請求及相關處理。Feign整合了Ribbon和Hystrix(關於Hystrix咱們後面再講),可讓咱們再也不須要顯式地使用這兩個組件。

Feign是以接口方式進行調用,而不是經過RestTemplate來調用,feign底層仍是ribbo,它進行了封裝,讓咱們調用起來更加happy.

 

經過客戶端進行負載均衡

新建一個客戶端

pom配置

<dependencies>
<!--公共代碼依賴-->
<dependency>
<groupId>cn.itsource.springcloud</groupId>
<artifactId>User_interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

<!--springboot支持-->
<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>

<!--eureka客戶端,服務消費者也要從註冊中心獲取可用服務列表-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<!--feign的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>

  配置yml

server:
  port: 9002
eureka:
  client:
    registerWithEureka: false #不註冊到Eureka,不在註冊中心顯示
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka

主方法

    @SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = "cn.itsource.microservice") //不在當前包下面
public class UserConsumerFeign9002Application {

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

寫一個接口,這個接口中的方法要和服務提供者裏面訪問地址和參數等保持一致。

@FeignClient(value = "USER-PROVIDER")
@RequestMapping("/provider")
public interface UserCilent {
@RequestMapping("/user/{id}") //user/1
User getUser(@PathVariable("id") Long id);
}

Controller中進行調用

@RestController
@RequestMapping("/consumer")
public class UserController {
@Autowired
private UserCilent userCilent;
@RequestMapping("/user/{id}")
public User getUser(@PathVariable("id")Long id){
        System.out.println(userCilent.getClass());
return userCilent.getUser(id);
    }
}
相關文章
相關標籤/搜索