1. 程式人生 > >Java架構學習(四十一)SpringCloud&基礎回顧&使用Fegin客戶端呼叫&服務雪崩效應產生原因&Jmeter模擬服務雪崩效應&解決雪崩效應辦法&Hystrix解決雪崩效應&相關面試

Java架構學習(四十一)SpringCloud&基礎回顧&使用Fegin客戶端呼叫&服務雪崩效應產生原因&Jmeter模擬服務雪崩效應&解決雪崩效應辦法&Hystrix解決雪崩效應&相關面試

前置知識

SpringCloud 是微服務解決框架,主要應用在RPC遠端呼叫。
2、裡面集成了Eureka註冊中心、Ribbon負載均衡客戶端、Zuul介面閘道器
	分散式配置中心。
3、SpringCloud客戶端呼叫工具、rest、fegin。
4、SpringCloud斷路器Hystrix服務降級、熔斷機制、限流。

其實總結高併發就一句話:通過負載均衡達和反向代理達到分流、通過限流達到防服務雪崩、通過服務降級達到部分故障服務依舊可用、通過隔離達到當某些服務故障不影響到其他服務、通過設定超時時間與重試機制達到防止請求堆積

一、使用Fegin客戶端呼叫工具

	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>
  <groupId>com.leeue</groupId>
  <artifactId>41_service-order-fegin</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<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.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-feign</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.RC1</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
  
</project>
MemberFegin.java    fegin呼叫service
package com.leeue.service;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @classDesc: 功能描述:(使用fegin來呼叫介面)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年11月11日 下午7:28:19
 */
@FeignClient(value="service-member") // 這上面value值寫你要呼叫的服務名稱
public interface MemberFegin {

	@RequestMapping("/getMemberAll") // 這上面寫你要呼叫的服務的介面地址 也就是service-member服務立馬的Mapping
	public List<String> getToOrderMemberAll();
	
	//Fegin底層也是會發出HttpClient請求來進行呼叫service-member服務地址
}

OrderFeginController.java   控制層
package com.leeue.controller;

import java.util.List;

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

import com.leeue.service.MemberFegin;

@RestController
public class OrderFeginController {
	
	@Autowired
	private MemberFegin memberFegin;
	@RequestMapping("/getToOrderMemberAll")
	public List<String> getToOrderMemberAll(){
		System.out.println("order fegin 工程呼叫 member工程");
		return memberFegin.getToOrderMemberAll();
	}
}

application.yml檔案
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8888/eureka/
server:
  port: 8765
spring:
  application:
    name: service-order-fegin
OrderFegin.java
package com.leeue;

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

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients   // 使用Fegin來呼叫服務 要在啟動類上加上這個註解
public class OrderFegin {
	
	public static void main(String[] args) {
		SpringApplication.run(OrderFegin.class, args);
	}
}
呼叫連結:http://localhost:8765/getToOrderMemberAll
要注意的是fegin裡面是自帶負載均衡的。路由策略是輪訓機制

二、服務雪崩效應產生原因

什麼是服務雪崩效應?
答:雪崩效應,所有的請求在處理一個服務,這個時候
就會產生服務堆積,就不能進行訪問改服務的其他介面了。
解決方案:
1、使用超時機制、服務降級()
	服務降級:就是在服務呼叫介面的時候如果發生錯誤或者超時的情況下,
	就不讓其呼叫介面,呼叫本地的fallback,返回服務錯誤,或者服務請求過多這種提示。

三、模擬服務雪崩效應操作使用Jmeter來模擬

在這裡插入圖片描述

在這裡插入圖片描述 在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述 在這裡插入圖片描述

在這裡插入圖片描述 在這裡插入圖片描述

在這裡插入圖片描述

四、解決雪崩效應的方法

服務雪崩產生原因:是因為服務產生了堆積,導致了該服務的其他介面無法被呼叫。
如何解決服務雪崩效應?
1、設定超時機制 --- 如果訂單服務呼叫會員服務介面沒有在 規定的時間響應回	
      來就返回給客戶端說連線超時等訊息
 2、使用服務降級:服務介面發生錯誤的時候,不去呼叫介面,呼叫本地方法。
 	  在SpringCloud 中是 fallback。本地方法。給客戶端一個反饋結果:
 	  當前訪問人數過多請稍後重試等訊息。
 3、熔斷機制:類似保險絲。--- 一旦達到了規定請求數量、就熔斷報錯  
    -- 服務降級類似
 4、使用服務的隔離機制 --- 每個服務介面都把隔離開來。
 A介面
 	自己有獨立的執行緒池、
 B介面
 	執行緒池  在A介面有大量訪問的時候不影響B介面的訪問。
 5、服務的限流機制。
 	使用閘道器zuul 或 nginx來做 介面達到一定次數的時候 就返回錯誤。

五、使用SpringCloud中Hystrix實現服務的降級

Hystrix 斷路器:當我們使用rpc遠端呼叫的時候,解決服務雪崩效應。
hystrix是專門解決服務與服務之間的報錯資訊。
hystrix:斷路器,裡面有服務降級、熔斷機制、服務隔離。

在使用hystrix專案中pom.xml檔案加入
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
application.yml檔案
# 開啟hystrix 斷路器
feign:
  hystrix:
     enabled: true
啟動OrderFegin這個服務 

在這裡插入圖片描述

	再次訪問的時候就就沒有轉圈,而是直接丟擲服務異常這種。
	在SpringCloud中預設服務之間呼叫服務要在1秒內返回結果。
	這裡是要3秒才能返回結果,所以hystrix進行了服務的降級
	這裡使用了服務降級。

在application.yml設定超時時間。
###超時時間
hystrix:
   command: 
     default: 
       execution: 
        isolation:
         thread: 
          timeoutInMilliseconds: 4000
	超時時間在5-10秒之間

解決程式碼:
package com.leeue.fallback;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.leeue.service.MemberFegin;

/**
 * @classDesc: 功能描述:(使用hystrix 斷路器做的服務降級)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年11月14日 上午11:50:51
 */
@Component //注入到Spring容器裡面去
public class MemberFallBack implements MemberFegin{

	/**
	 * 對 getToOrderMemberAll這個介面進行服務降級處理
	 */
	// 這個是講課的例子  在公司裡面 不是返回型別是 String的
	@Override
	public List<String> getToOrderMemberAll() {
		//做服務的降級處理
		List<String> list = new ArrayList<String>();
		list.add("服務發生異常....當前不能訪問");
		return list;
	}

}
package com.leeue.service;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

import com.leeue.fallback.MemberFallBack;

/**
 * @classDesc: 功能描述:(使用fegin來呼叫介面)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年11月11日 下午7:28:19
 */
@FeignClient(value="service-member",fallback=MemberFallBack.class) // 這上面value值寫你要呼叫的服務名稱
public interface MemberFegin {

	@RequestMapping("/getMemberAll") // 這上面寫你要呼叫的服務的介面地址 也就是service-member服務立馬的Mapping
	public List<String> getToOrderMemberAll();
	
	//Fegin底層也是會發出HttpClient請求來進行呼叫service-member服務地址
}

六、使用hystrix解決服務雪崩效應

	上面是fegin  呼叫解決雪崩效應,使用的是服務降級

七、SpringCloud相關面試

1、微服務情況下,怎麼解決服務雪崩效應。
答:使用hystrix、服務降級、服務隔離、使用閘道器限流
2、SpringCloud與SpringBoot區別
答:SpringBoot解決的問題是,能快速整合第三方框架,
簡化xml配置,自帶容器,預設整合web元件springMVC
SpringCloud微服務解決框架依賴與SpringBoot.
使用SpringMVC作為RPC呼叫框架書寫介面。

有A服務 B服務 怎麼讓B 服務只能讓A服務訪問 解決方案: 在微服務裡面使用介面閘道器 來判斷介面請求來源是那個服務 底層原理是判斷http請求來源