目錄
eureka的作用
# eureka叢集搭建
app消费者
负载均衡策略在消费端配置的缺点
首頁 Java java教程 SpringCloud的微服務部署詳解

SpringCloud的微服務部署詳解

Oct 27, 2018 am 11:56 AM
docker java mysql spring springcloud

這篇文章帶給大家的內容是關於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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

MySQL和PhpMyAdmin:核心功能和功能 MySQL和PhpMyAdmin:核心功能和功能 Apr 22, 2025 am 12:12 AM

MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

Linux上的Docker:Linux系統的容器化 Linux上的Docker:Linux系統的容器化 Apr 22, 2025 am 12:03 AM

Docker在Linux上重要,因為Linux是其原生平台,提供了豐富的工具和社區支持。 1.安裝Docker:使用sudoapt-getupdate和sudoapt-getinstalldocker-cedocker-ce-clicontainerd.io。 2.創建和管理容器:使用dockerrun命令,如dockerrun-d--namemynginx-p80:80nginx。 3.編寫Dockerfile:優化鏡像大小,使用多階段構建。 4.優化和調試:使用dockerlogs和dockerex

如何安全地將包含函數和正則表達式的JavaScript對象存儲到數據庫並恢復? 如何安全地將包含函數和正則表達式的JavaScript對象存儲到數據庫並恢復? Apr 19, 2025 pm 11:09 PM

安全地處理JSON中的函數和正則表達式在前端開發中,經常需要將JavaScript...

容器化技術(例如Docker)如何影響Java平台獨立性的重要性? 容器化技術(例如Docker)如何影響Java平台獨立性的重要性? Apr 22, 2025 pm 06:49 PM

容器化技術如Docker增強而非替代Java的平台獨立性。 1)確保跨環境的一致性,2)管理依賴性,包括特定JVM版本,3)簡化部署過程,使Java應用更具適應性和易管理性。

在MySQL中解釋外鍵的目的。 在MySQL中解釋外鍵的目的。 Apr 25, 2025 am 12:17 AM

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

生產環境下部署SAAS應用:如何用Docker Swarm實現前端UI和Java應用的編排? 生產環境下部署SAAS應用:如何用Docker Swarm實現前端UI和Java應用的編排? Apr 19, 2025 pm 09:21 PM

在生產環境中部署SAAS應用:Docker...

MySQL與Oracle有何不同? MySQL與Oracle有何不同? Apr 22, 2025 pm 05:57 PM

MySQL適合快速開發和中小型應用,Oracle適合大型企業和高可用性需求。 1)MySQL開源、易用,適用於Web應用和中小型企業。 2)Oracle功能強大,適合大型企業和政府機構。 3)MySQL支持多種存儲引擎,Oracle提供豐富的企業級功能。

Docker:容器化工具,Kubernetes:編排者 Docker:容器化工具,Kubernetes:編排者 Apr 21, 2025 am 12:01 AM

Docker是容器化工具,Kubernetes是容器編排工具。 1.Docker打包應用及其依賴成容器,可在任何支持Docker的環境中運行。 2.Kubernetes管理這些容器,實現自動化部署、擴展和管理,使應用高效運行。

See all articles