前言
微服務(wù)開發(fā)需要用到服務(wù)間的調(diào)用Feign暖眼、也可以選擇dubbo牙瓢,但是dubbo上手有點難度,可參考另一篇文章http://www.reibang.com/p/e11ff097424b
至于他們的優(yōu)缺點,一個是rpc一個是http rest。Feign較帶寬資源敬扛,對我們來說這點帶寬還不是事,下面基于Feign來實現(xiàn)負(fù)載均衡和熔斷朝抖,我們拿一個user的服務(wù)為例子啥箭。
第一篇-使用:http://www.reibang.com/p/7af37be1bedb
第二篇-熔斷限流:http://www.reibang.com/p/2945c88950d9
源碼:https://github.com/xcocean/spring-cloud-feign-demo
Feign的調(diào)用總結(jié)就是我開啟feign調(diào)用另一個服務(wù)的接口(controller),另一個服務(wù)不需要feign治宣,只需要注冊在一起的集群下捉蚤。
技術(shù)棧
1抬驴、負(fù)載均衡:spring boot 2.1.x
+nacos注冊中心
+Feign
2炼七、熔斷:
關(guān)于spring boot的版本缆巧,我們先選擇現(xiàn)在最新穩(wěn)定的2.1.102020年2月22日
2.2.x可能有點坑,先不用它豌拙。
一陕悬、創(chuàng)建聚合項目
parent(root)
|__dependencies:依賴
|__user-service:服務(wù)提供者
|__user-feign:服務(wù)調(diào)用者(調(diào)用一方使用feign)
創(chuàng)一個文件夾:spring-cloud-feign-demo
使用idea打開,在創(chuàng)建pom.xml:如下:
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.qbccn</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<url>http://www.qbccn.com</url>
<description>spring cloud feign 演示demo</description>
<modules>
<module>dependencies</module>
<module>user-service</module>
<module>user-feign</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.qbccn</groupId>
<artifactId>dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring-javaformat.version>0.0.12</spring-javaformat.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
<version>${spring-javaformat.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- 設(shè)置默認(rèn)跳過測試 -->
<includes>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
</excludes>
<systemPropertyVariables>
<java.security.egd>file:/dev/./urandom</java.security.egd>
<java.awt.headless>true</java.awt.headless>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-rules</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>commons-logging:*:*</exclude>
</excludes>
<searchTransitive>true</searchTransitive>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<inherited>true</inherited>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
在spring-cloud-feign-demo
下創(chuàng)建dependencies
按傅,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.qbccn</groupId>
<artifactId>dependencies</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<url>http://www.qbccn.com</url>
<properties>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<spring-cloud-alibaba.verion>0.9.0.RELEASE</spring-cloud-alibaba.verion>
<spring-cloud-starter-feign.version>1.4.7.RELEASE</spring-cloud-starter-feign.version>
<spring-cloud-starter-alibaba-nacos-discovery.version>0.9.0.RELEASE
</spring-cloud-starter-alibaba-nacos-discovery.version>
<spring-cloud-starter-alibaba-sentinel.version>2.1.1.RELEASE</spring-cloud-starter-alibaba-sentinel.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.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.verion}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>${spring-cloud-starter-feign.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>${spring-cloud-starter-alibaba-nacos-discovery.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${spring-cloud-starter-alibaba-sentinel.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<name>Spring Milestone</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshot</id>
<name>Spring Snapshot</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
二捉超、創(chuàng)建服務(wù)生產(chǎn)者
接著創(chuàng)建服務(wù)提供者user-service
,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.qbccn</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-service</artifactId>
<packaging>jar</packaging>
<url>http://www.qbccn.com</url>
<inceptionYear>2020-Now</inceptionYear>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 10000
spring:
application:
name: user-service
main:
allow-bean-definition-overriding: true
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
nacos:
discovery:
server-addr: 192.168.112.1:8848 # 注意改成你的nacos地址
UserServiceApplication如下:
package com.qbccn.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient //注冊服務(wù)
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
編寫普通的controller唯绍、service和實現(xiàn)接口
package com.qbccn.userservice.controller;
import com.qbccn.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author linke
* @date 2020-02-21 下午 22:59
* @description
*/
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("info")
public Object info() {
return userService.getInfo();
}
}
package com.qbccn.userservice.service;
public interface UserService {
/**
* 獲取用戶信息
*/
Object getInfo();
}
package com.qbccn.userservice.service.impl;
import com.qbccn.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component //交給spring托管
public class UserServiceImpl implements UserService {
// 用于顯示負(fù)載均衡拼岳,端口區(qū)分
@Value("${server.port}")
private int port;
@Override
public Object getInfo() {
System.out.println("被調(diào)用!當(dāng)前端口:" + port);
Map<String, Object> map = new HashMap<>();
map.put("name", "張三");
map.put("age", 23);
map.put("sex", "男");
map.put("port", port);
return map;
}
}
1况芒、然后啟動項目惜纸,
2、勾選上绝骚,然后修改application的端口為10000耐版,再啟動一次項目
3、登陸nacos可以看到已經(jīng)被注冊上:
三压汪、創(chuàng)建服務(wù)消費(fèi)者(Feign)
spring-cloud-feign-demo
下創(chuàng)建文件夾user-feign
粪牲,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.qbccn</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-feign</artifactId>
<packaging>jar</packaging>
<url>http://www.qbccn.com</url>
<inceptionYear>2020-Now</inceptionYear>
<dependencies>
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot End -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
</project>
application.yml配置如下
spring:
application:
name: user-feign
main:
allow-bean-definition-overriding: true
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
cloud:
nacos:
discovery:
server-addr: 192.168.112.1:8848
application.java需要開啟feign:
package com.qbccn.userfeign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient //注冊服務(wù)
@EnableFeignClients //開啟feign客戶端
public class UserFeignApplication {
public static void main(String[] args) {
SpringApplication.run(UserFeignApplication.class, args);
}
}
接著是controller:
package com.qbccn.userfeign.controller;
import com.qbccn.userfeign.feign.UserServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("user")
public class UserFeignController {
@Autowired
private UserServiceFeign userServiceFeign;
@GetMapping("info")
@ResponseBody
public Object info() {
return userServiceFeign.GetInfo();
}
}
feign,自行看包路徑創(chuàng)建
package com.qbccn.userfeign.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 說明一下止剖,這個user-service是指服務(wù)提供者腺阳,注冊到nacos上的,不區(qū)分大小寫
* path 表示是user-service服務(wù)下的 /user/info 這個路徑
*/
@FeignClient(value = "user-service", path = "user")
public interface UserServiceFeign {
@GetMapping(value = "info")
Object GetInfo();
}
然后啟動服務(wù)穿香,訪問http://localhost:8080/user/info亭引,不斷刷新效果如下:
可以看出這是一個輪詢機(jī)制,可以配置權(quán)重
實現(xiàn)熔斷
像這樣開發(fā)扔水,如果10000端口的服務(wù)突然網(wǎng)絡(luò)震蕩痛侍,請求失敗了,我們需要使用熔斷來返回失敗結(jié)果魔市,由于篇幅主届,我將在下一篇文章說明