首頁  >  文章  >  Java  >  SpringCloud的微服務部署詳解

SpringCloud的微服務部署詳解

不言
不言轉載
2018-10-27 11:56:245891瀏覽

這篇文章帶給大家的內容是關於SpringCloud的微服務部署詳解,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

微服務的其中一個特點就是有許許多的粒度小(功能單一,例如用戶管理,簡訊發送管理,郵件發送管理,文件管理等)、能獨立部署、擴展、運行的小應用,可以稱為api,也就是服務提供者。 api之間可以互相調用,但更多的是供app調用,例如學生管理系統,它是面向用戶的,是許許多多功能的集合體,它需要調用許多api完成業務功能,所以這學生管理系統可以稱為app。

eureka的作用

傳統的單體應用程式開發,就是將api和app的程式碼全部整合在一起,在同一個進程中運行,對應java web通俗的說就是全部打包在一個war中部署在一個tomcat中運行。而微服務的每個api,app都擁有自己的流程,也就是都有自己的tomcat,某個api掛了,不影響其他api和app運作。

SpringCloud的微服務部署詳解

api是採取restfull風格暴漏出去的,所以app(api)呼叫api時,採取http://ip:埠這形式進行通訊。那麼問題來了,如果有很多app都調用了某個api,如果api的ip或端口發生了更改,如果app中對api的ip和端口等信息是寫在配置文件的,難道要通知每個app ,說這個api的位址和連接埠變了,app要進行修改重新編譯部署(這是舉例子而已,實際情況有些企業對常量的配置可能寫配置文件,也可能寫數據庫)。這太麻煩了,如果api的位址和連接埠有變化,app能及時獲知自行變更,那就好了。還有個弊端,就是api是否掛了,也沒辦法直觀觀察到。

所以,如果在app和api之間增加個服務管理中心,api像服務管理中心註冊信息,app從服務管理中心獲取api的信息,api有個唯一標識,api有變更的時候通知服務管理中心,服務管理中心通知相關的app或app定時從服務管理中心獲取最新的api訊息,同時服務管理中心具有很高的穩定性、可靠性。

eureka就是為了這樣的一個服務管理中心,下面是我根據自己的理解畫的一張圖。

SpringCloud的微服務部署詳解

下面這張是官方的架構圖

SpringCloud的微服務部署詳解

1.Application Service 相當於服務提供者/api

2.Application Client 相當於服務消費者/app

3.Make Remote Call,其實就是實作服務的使用/例如httpClient, restTemplate

4.us-east-1 Eureka 叢集服務

5.us-east-1c、us-east-1d、us-east-1e 就是具體的某個eureka

Eureka:

  1. 是純正的servlet 應用,需建置成war套件部署

  2. 使用了Jersey 框架實現自身的RESTful HTTP介面

  3. peer之間的同步與服務的註冊全部透過HTTP 協定實作

  4. 定時任務(傳送心跳、定時清理過期服務、節點同步等)透過JDK 自帶的Timer 實作

  5. #記憶體快取使用Google的guava套件實作

# eureka叢集搭建

和eureka類似功能的有zookeeper,etcd等。 spring boot已經整合了eureka,所以我們可以像spring boot那樣搭建環境,部署運行。

我是在window10下使用eclipse學習的。

準備工作。

在修改hosts文件,在最後加上(位置:C:WindowsSystem32driversetc)

127.0.0.1 01.eureka.server 
127.0.0.1 02.eureka.server 
127.0.0.1 03.eureka.server

eclipse下建立個普通的maven專案eureka-server。

pom.xml

 <project 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.fei.springcloud</groupid> 
 <artifactid>springcloud-eureka-server</artifactid> 
 <version>0.0.1-SNAPSHOT</version> 
 <description>eureka服务端</description> 
<!-- 依赖仓库 设置从aliyun仓库下载 --> 
<repositories> 
<repository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
<enabled>true</enabled> 
</releases> 
</repository> 
</repositories> 
<!-- 插件依赖仓库 --> 
<pluginrepositories> 
<pluginrepository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
 <enabled>true</enabled> 
</releases> 
</pluginrepository> 
</pluginrepositories> 
<properties> 
<!-- 文件拷贝时的编码 --> 
<project.build.sourceencoding>UTF-8</project.build.sourceencoding> 
<project.reporting.outputencoding>UTF-8</project.reporting.outputencoding> 
<!-- 编译时的编码 --> 
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> 
<java.version>1.8</java.version> 
<maven.compiler.source>1.8</maven.compiler.source> 
<maven.compiler.target>1.8</maven.compiler.target> 
</properties> 
<parent> 
<groupid>org.springframework.boot</groupid> 
<artifactid>spring-boot-starter-parent</artifactid> 
<version>1.5.2.RELEASE</version> 
<relativepath></relativepath> 
</parent> 
<dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-starter-eureka-server</artifactid> 
</dependency> 
</dependencies> 
<dependencymanagement> 
<dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-dependencies</artifactid> 
<version>Dalston.RELEASE</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> 
</project>

啟動類別Application.java

package com.fei.springcloud; 
import org.springframework.boot.SpringApplication; 
 import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 
@EnableEurekaServer 
@SpringBootApplication 
public class Application { 
 public static void main(String[] args) { 
SpringApplication.run(Application.class, args); 
} 
}

注意註解:@EnableEurekaServer,表示這是server服務

#設定檔application.properties

logging.config=classpath:logback.xml 
logging.path=d:/logs 
##tomcat set### 
# eureka的默认端口是8761 
server.port=8081 
server.session-timeout=60 
########### 
spring.application.name=eureka-server-01 
####下面2个一定要false,因为这程序是要作为服务端

但是jar中存在eureka-client.jar,所以要false,否则启动会报错的 
#是否注册到eureka 
eureka.client.register-with-eureka=false 
#是否获取注册信息 
eureka.client.fetch-registry=false 

#为了便于测试,取消eureka的保护模式,如果启动的话,

比如api提供者关闭了,但是eureka仍然保留信息 
eureka.server.enable-self-preservation=false 
#服务名称 
eureka.instance.hostname=01.server.eureka 
#eureka的服务地址,/eureka是固定的 
eureka.client.serviceUrl.defaultZone=http://02.

server.eureka:8082/eureka/,http://03.server.eureka:8083/eureka/

注意:eureka.client.serviceUrl.defaultZone的配置,如果是01,則填入02、03的位址和連接埠;如果是02,則填入01、03的位址和端口,也就是說讓01,02,03這3個eureka服務能相互間同步數據,如果是01->02->03->01,則api提供者註冊資訊到01時,01會同步資料到02,但02不會同步到03,01也不會同步到03,也就是說03缺資料了。看原始碼,服務的註冊資訊不會被二次傳播,看PeerAwareInstanceRegistryImpl.java

#

SpringCloud的微服務部署詳解

启动01 eureka,然后修改application.properties,变为02 eureka的配置

logging.config=classpath:logback.xml 
logging.path=d:/logs 
##tomcat set### 
# eureka的默认端口是8761 
server.port=8082 
server.session-timeout=60 
########### 
spring.application.name=eureka-server-02 
####下面2个一定要false,因为这程序是要作为服务端,

但是jar中存在eureka-client.jar,所以要false,否则启动会报错的 
#是否注册到eureka 
eureka.client.register-with-eureka=false 
#是否获取注册信息 
eureka.client.fetch-registry=false 
#为了便于测试,取消eureka的保护模式,如果启动的话,

比如api提供者关闭了,但是eureka仍然保留信息 
eureka.server.enable-self-preservation=false 
#服务名称 
eureka.instance.hostname=02.server.eureka 
#eureka的服务地址,/eureka是固定的 
eureka.client.serviceUrl.defaultZone=http://01.server.

eureka:8081/eureka/,http://03.server.eureka:8083/eureka/

然后执行启动类,03也是一样的操作。

浏览器访问http://01.server.eureka:8081/(或者http://02.server.eureka:8082/,或者http://03.server.eureka:8083/)看到

SpringCloud的微服務部署詳解

api提供者

创建个普通的maven项目eureka-api,该api是个用户服务提供者。采取spring boot开发模式

SpringCloud的微服務部署詳解

pom.xml

<project> 
<modelversion>4.0.0</modelversion> 
<groupid>com.fei.springcloud</groupid> 
<artifactid>springcloud-eureka-server</artifactid> 
<version>0.0.1-SNAPSHOT</version> 
<description>eureka服务端</description> 
<!-- 依赖仓库 设置从aliyun仓库下载 --> 
<repositories> 
<repository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
<enabled>true</enabled> 
</releases> 
</repository> 
</repositories> 
<!-- 插件依赖仓库 --> 
<pluginrepositories> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
<enabled>true</enabled> 
</releases> 
 
</pluginrepositories> 
<properties> 
<!-- 文件拷贝时的编码 --> 
<project.build.sourceencoding>UTF-8</project.build.sourceencoding> 
<project.reporting.outputencoding>UTF-8</project.reporting.outputencoding> 
<!-- 编译时的编码 --> 
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> 
<java.version>1.8</java.version> 
<maven.compiler.source>1.8</maven.compiler.source> 
<maven.compiler.target>1.8</maven.compiler.target> 
</properties> 
<parent> 
<groupid>org.springframework.boot</groupid> 
<artifactid>spring-boot-starter-parent</artifactid> 
<version>1.5.2.RELEASE</version> 
 <relativepath></relativepath> 
</parent> 
<dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-starter-eureka</artifactid> 
</dependency> 
</dependencies> 
<dependencymanagement> 
<dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-dependencies</artifactid> 
<version>Dalston.RELEASE</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> 
 </project>

它和eureka 服务端,有个依赖是不一样的。

application.properties

logging.config=classpath:logback.xml 
logging.path=d:/logs 
##tomcat set### 
# eureka的默认端口是8761 
server.port=9081 
server.session-timeout=60 
########### 
spring.application.name=api-user-server 
#像eureka服务注册信息时,使用ip地址,默认使用hostname 
eureka.instance.preferIpAddress=true 
#服务的instance-id默认默认值是${spring.cloud.client.hostname

:${spring.aplication.name}

:${spring.application.instance_id:${server.port}} , 
#也就是机器主机名:应用名称:应用端口 
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} 
#eureka的服务地址 
eureka.client.serviceUrl.defaultZone=http://01.server.eureka:8081/eureka/

Application.java

 package com.fei.springcloud; 
 import org.springframework.boot.SpringApplication; 
 import org.springframework.boot.autoconfigure.SpringBootApplication; 
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 
 @EnableEurekaClient 
 @SpringBootApplication 
 public class Application { 
 public static void main(String[] args) { 
 SpringApplication.run(Application.class, args); 
 } 
 }

@EnableEurekaClient,不管是消费者还是提供者,对应eureka server来说都是客户端client

写个普通的controller,UserProvider.java.提供个根据id获取用户信息的接口

 package com.fei.springcloud.provider; 
 import javax.servlet.http.HttpServletRequest; 
 import org.springframework.web.bind.annotation.GetMapping; 
 import org.springframework.web.bind.annotation.PathVariable; 
 import org.springframework.web.bind.annotation.RequestMapping; 
 import org.springframework.web.bind.annotation.RestController; 
 @RestController 
 @RequestMapping("/user") 
 public class UserProvider { 
 @GetMapping(value="/find/{id}") 
 public String find(@PathVariable("id") String id,HttpServletRequest request){ 
 //实际项目中,这里可以使用JSONObject,返回json字符串 
 //为了便于测试消费者app的负载均衡,返回服务端端口 
 String s = "张三"+" 服务端端口:"+request.getLocalPort(); 
  return s; 
 } 
 }

执行Application.java,将application.properties的端口修改为9082,再次执行

浏览器访问http://01.server.eureka:8081/

SpringCloud的微服務部署詳解

Application就是文件中定义的spring.application.name=api-user-server,它会自动转为大写

如果想免费学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java进阶群:478030634,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

app消费者

在Spring Cloud Netflix中,使用Ribbon实现客户端负载均衡,使用Feign实现声明式HTTP客户端调用——即写得像本地函数调用一样.

SpringCloud的微服務部署詳解

ribbo负载均衡的app消费者

创建个普通的maven项目eureka-app-ribbo.

pom.xml

<project 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.fei.springcloud</groupid> 
<artifactid>springcloud-eureka-app-ribbo</artifactid> 
<version>0.0.1-SNAPSHOT</version> 
<description>eureka消费者ribbo</description> 
<!-- 依赖仓库 设置从aliyun仓库下载 --> 
<repositories> 
<repository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
<enabled>true</enabled> 
</releases> 
</repository> 
</repositories> 
<!-- 插件依赖仓库 --> 
<pluginrepositories> 
<pluginrepository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
<snapshots> 
<enabled>true</enabled> 
</snapshots> 
<releases> 
<enabled>true</enabled> 
</releases> 
</pluginrepository> 
</pluginrepositories> 
<properties> 
<!-- 文件拷贝时的编码 --> 
<project.build.sourceencoding>UTF-8</project.build.sourceencoding> 
<project.reporting.outputencoding>UTF-8</project.reporting.outputencoding>
<!-- 编译时的编码 --> 
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> 
<java.version>1.8</java.version> 
<maven.compiler.source>1.8</maven.compiler.source> 
<maven.compiler.target>1.8</maven.compiler.target> 
</properties> 
<parent> 
<groupid>org.springframework.boot</groupid> 
<artifactid>spring-boot-starter-parent</artifactid> 
<version>1.5.2.RELEASE</version> 
<relativepath></relativepath> 
</parent> 
<dependencies> 
<!-- 客户端负载均衡 --> 
<dependency> 
 <groupid>org.springframework.cloud</groupid> 
 <artifactid>spring-cloud-starter-ribbon</artifactid> 
 </dependency> 
 <!-- eureka客户端 --> 
 <dependency> 
 <groupid>org.springframework.cloud</groupid> 
 <artifactid>spring-cloud-starter-eureka</artifactid> 
 </dependency> 
 <!-- spring boot实现Java Web服务 --> 
 <dependency> 
<groupid>org.springframework.boot</groupid> 
<artifactid>spring-boot-starter-web</artifactid> 
</dependency> 
</dependencies> 
<dependencymanagement> 
 <dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-dependencies</artifactid> 
<version>Dalston.RELEASE</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> 
</project>

application.properties

logging.config=classpath:logback.xml 
logging.path=d:/logs 
##tomcat set### 
# eureka的默认端口是8761 
server.port=7081 
server.session-timeout=60 
########### 
spring.application.name=app-user 
#像eureka服务注册信息时,使用ip地址,默认使用hostname 
eureka.instance.preferIpAddress=true 
#服务的instance-id默认默认值是${spring.cloud.client.hostname}${spring.application.name}

:${spring.application.instance_id:${server.port}} , 
#也就是机器主机名:应用名称:应用端口 
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} 
#eureka的服务地址 
eureka.client.serviceUrl.defaultZone=http://01.server.eureka:

8081/eureka/,http://02.server.eureka:8082/eureka/,

http://03.server.eureka:8083/eureka/

UserController.java

 logging.config=classpath:logback.xml 
 logging.path=d:/logs 
 ##tomcat set### 
 # eureka的默认端口是8761 
 server.port=7081 
 server.session-timeout=60 
 ########### 
 spring.application.name=app-user 
 #像eureka服务注册信息时,使用ip地址,默认使用hostname 
 eureka.instance.preferIpAddress=true 
 #服务的instance-id默认默认值是${spring.cloud.client.hostname}

 :${spring.application.name}:${spring.application.instance_id:${server.port}} , 
 #也就是机器主机名:应用名称:应用端口 
 eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} 
 #eureka的服务地址 
 eureka.client.serviceUrl.defaultZone=http://01.server.eureka:8081/eureka/

 ,http://02.server.eureka:8082/eureka/,http://03.server.eureka:8083/eureka/

使用restTemplate需要自己拼接url

启动类Application.java

package com.fei.springcloud; 
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; 
@EnableEurekaClient 
@SpringBootApplication 
public class Application { 
@Bean //定义REST客户端,RestTemplate实例 
@LoadBalanced //开启负债均衡的能力 
RestTemplate restTemplate() { 
return new RestTemplate(); 
} 
public static void main(String[] args) { 
SpringApplication.run(Application.class, args); 
} 
}

eureka服务

SpringCloud的微服務部署詳解

浏览器访问http://127.0.0.1:7081/user/find

看到信息“张三 服务端端口:9081”,刷新浏览器看到“张三 服务端端口:9082”,说明的确是有负载均衡。

但是访问外网的时候,http://127.0.0.1:7081/user/test,也就是域名不在eureka注册过的,就不行了。

SpringCloud的微服務部署詳解

以后再研究下如何解决。

feign的app消费者

feign可以写个接口,加上相关的注解,调用的时候,会自动拼接url,调用者就像调用本地接口一样的操作。

Feign也用到ribbon,当你使用@ FeignClient,ribbon自动被应用。

像ribbo创建个项目,或者直接在ribbo项目修改都OK。

pom.xml 把ribbo的依赖修改为feign

<project 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.fei.springcloud</groupid> 
<artifactid>springcloud-eureka-app-feign</artifactid> 
<version>0.0.1-SNAPSHOT</version> 
<description>eureka消费者feign</description> 
<!-- 依赖仓库 设置从aliyun仓库下载 --> 
<repositories> 
<repository> 
<id>alimaven</id> 
<url>http://maven.aliyun.com/nexus/content

 /repositories/central/</url> 
 <snapshots> 
 <enabled>true</enabled> 
 </snapshots> 
 <releases> 
 <enabled>true</enabled> 
 </releases> 
 </repository> 
 </repositories> 
 <!-- 插件依赖仓库 --> 
 <pluginrepositories> 
 <pluginrepository> 
 <id>alimaven</id> 
 <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> 
 <snapshots> 
 <enabled>true</enabled> 
 </snapshots> 
 <releases> 
 <enabled>true</enabled> 
 </releases> 
 </pluginrepository> 
 </pluginrepositories> 
 <properties> 
 <!-- 文件拷贝时的编码 --> 
  <project.build.sourceencoding>UTF-8</project.build.sourceencoding> 
 <project.reporting.outputencoding>UTF-8</project.reporting.outputencoding> 
 <!-- 编译时的编码 --> 
 <maven.compiler.encoding>UTF-8</maven.compiler.encoding> 
 <java.version>1.8</java.version> 
 <maven.compiler.source>1.8</maven.compiler.source> 
 <maven.compiler.target>1.8</maven.compiler.target> 
 </properties> 
 <parent> 
 <groupid>org.springframework.boot</groupid> 
 <artifactid>spring-boot-starter-parent</artifactid> 
 <version>1.5.2.RELEASE</version> 
 <relativepath></relativepath> 
 </parent> 
 <dependencies> 
 <!-- Feign实现声明式HTTP客户端 --> 
 <dependency> 
 <groupid>org.springframework.cloud</groupid> 
 <artifactid>spring-cloud-starter-feign</artifactid> 
 </dependency> 
 <!-- eureka客户端 --> 
 <dependency> 
 <groupid>org.springframework.cloud</groupid> 
 <artifactid>spring-cloud-starter-eureka</artifactid> 
 </dependency> 
 <!-- spring boot实现Java Web服务 --> 
 <dependency> 
 <groupid>org.springframework.boot</groupid> 
 <artifactid>spring-boot-starter-web</artifactid> 
 </dependency> 
 </dependencies> 
 <dependencymanagement> 
 <dependencies> 
<dependency> 
<groupid>org.springframework.cloud</groupid> 
<artifactid>spring-cloud-dependencies</artifactid> 
<version>Dalston.RELEASE</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> 
</project>

application.properties和上面一样

logging.config=classpath:logback.xml 
logging.path=d:/logs 
##tomcat set### 
# eureka的默认端口是8761 
server.port=7081 
server.session-timeout=60 
########### 
spring.application.name=app-user 
#像eureka服务注册信息时,使用ip地址,默认使用hostname 
eureka.instance.preferIpAddress=true 
#服务的instance-id默认默认值是${spring.cloud.client.hostname}
:${spring.application.name}:${spring.application.instance_id:${server.port}} , 
#也就是机器主机名:应用名称:应用端口 
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port} 
#eureka的服务地址 
eureka.client.serviceUrl.defaultZone=http://01.server.eureka
8081/eureka/,http://02.server.eureka:8082/eureka/,
http://03.server.eureka:8083/eureka/

增加个UserService.java接口类

package com.fei.springcloud.service; 
import org.springframework.cloud.netflix.feign.FeignClient; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.PathVariable; 
@FeignClient("API-USER-SERVER") 
public interface UserService { 
@GetMapping(value="/user/find/{id}") 
String find(@PathVariable("id") String id); 
}

UserController.java

package com.fei.springcloud.controller; 
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; 
import com.fei.springcloud.service.UserService; 
@Controller 
@RequestMapping("/user") 
public class UserController { 
@Autowired 
private UserService userService; 
 @GetMapping(value = "/find") 
@ResponseBody 
public String find() { 
//url中对应api提供者的名称,全大写 
String s = userService.find("123"); 
return s; 
} 
}

浏览器访问http://127.0.0.1:7081/user/find,得到信息“张三 服务端端口:9081”,刷新,得到“张三 服务端端口:9082”,Feign也用到ribbon,当你使用@ FeignClient,ribbon自动被应用。所以也会负载均衡

ribbo负载均衡策略选择

SpringCloud的微服務部署詳解

AvailabilityFilteringRule:过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) | 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态

RandomRule:随机选择一个server

BestAvailabl:选择一个最小的并发请求的server,逐个考察Server,如果Server被tripped了,则忽略

RoundRobinRule:roundRobin方式轮询选择, 轮询index,选择index对应位置的server

WeightedResponseTimeRule:根据响应时间分配一个weight(权重),响应时间越长,weight越小,被选中的可能性越低

RetryRule:对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server

ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择server

ResponseTimeWeightedRule:作用同WeightedResponseTimeRule,二者作用是一样的,ResponseTimeWeightedRule后来改名为WeightedResponseTimeRule

在app消费者的application.properties配置文件中加入

#ribbo负载均衡策略配置,默认是依次轮询 
API-USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com. 
netflix.loadbalancer.RandomRule

其中API-USER-SERVER是api服务提供者的服务名称,也就是说,可以给每个不同的api服务提供者配置不同的复制均衡策略,验证就不贴图了

负载均衡策略在消费端配置的缺点

在上面的例子中,ribbon的负载均衡是在消费端完成的。流程是这样的:提供者服务A集群,启动2个进程A1,A2,都注册到eureka,app消费端根据api服务者名称获取到A1,A2的具体连接地址,ribbon就对A1,A2进行负载均衡。

缺点:

1) 如果所有的app消费端的配置策略不好,导致绝大部分的请求都到A1,那A1的压力就大了。也就是说负载策略不是有api提供者所控制的了(这里就不说A1,A2所在的服务器哪个性能更好了,因为如果app/api都是在Docker中运行,k8s负责资源调配的话,可以认为每个服务的进程所在的docker配置是一样的,比如A服务对应的A1,A2系统环境是一致的,B服务对应的B1,B2,B3系统环境是一致的,只是所对应的宿主机服务器估计不一样而已)。

2)如果api提供者需要开放给第三方公司的时候,总不能把A1,A2告诉第三方吧,说我们这A服务集群了,有A1,A2,你随意吧。

我们实际项目中的做法,都是每个提供者服务都有自己的nginx管理自己的集群,然后把nginx的域名提供给app消费者即可。之所以每个服务提供者都有自己的nginx,是因为docker被k8s管控的时候,ip都是变化的,需要更新到nginx中。如果A,B都共用一个nginx,那A重构建部署的时候,A1,A2的ip变化了,需要更新到nginx中去,那如果导致nginx出现问题了,岂不是影响到B的使用了,所以A,B都有自己的nginx。那spring cloud没有解决方案了吗?有。spring cloud集成了zuul,zuul服务网关,不但提供了和nginx一样的反向代理功能,还提供了负载均衡、监控、过滤等功能。

以上是SpringCloud的微服務部署詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除