>  기사  >  Java  >  SpringCloud의 마이크로서비스 배포에 대한 자세한 설명

SpringCloud의 마이크로서비스 배포에 대한 자세한 설명

不言
不言앞으로
2018-10-27 11:56:245884검색

이 기사는 Spring Cloud의 마이크로서비스 배포에 대한 자세한 설명을 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

마이크로서비스의 특징 중 하나는 독립적으로 배포, 확장, API용, 즉 서비스 제공자라고 할 수 있습니다. API는 서로 호출할 수 있지만 대부분은 앱에 의해 호출됩니다. 예를 들어 학생 관리 시스템은 사용자 중심이며 비즈니스 기능을 완성하려면 많은 API를 호출해야 하므로 이 학생 관리 시스템은 다음과 같습니다. 앱이라고 할 수 있습니다.

유레카의 역할

전통적인 단일 애플리케이션 개발은 API와 앱 코드를 함께 통합하여 동일한 프로세스에서 실행하는 것입니다. Java 웹에 해당하며 일반인의 관점에서는 모두 전쟁으로 패키징되어 Tomcat에 배포됩니다. 운영 중. 마이크로서비스의 각 API와 앱에는 자체 프로세스가 있습니다. 즉, 특정 API가 중단되더라도 다른 API와 앱의 작동에는 영향을 미치지 않습니다.

SpringCloud의 마이크로서비스 배포에 대한 자세한 설명

api는 Restfull 스타일로 노출되어 있어 앱(api)이 api를 호출하면 http://ip:port 형태로 통신합니다. 그러면 특정 API를 호출하는 앱이 많은 경우, API의 IP 또는 포트가 변경된 경우, 앱의 API IP 및 포트 정보가 구성 파일에 기록된 경우 이를 알려야 합니까? 각 앱은 이 API의 주소와 포트가 변경되었으며 앱을 수정하고 다시 컴파일하고 배포해야 한다고 말합니다. (이는 단지 예시일 뿐이며 실제 상황에서는 일부 회사에서 구성 파일이나 데이터베이스를 작성하여 상수를 구성할 수 있습니다.) . 이는 너무 번거로운 작업입니다. API의 주소와 포트가 변경되면 앱이 시간에 따라 변경 사항을 학습할 수 있으면 좋을 것입니다. 또 다른 단점은 API가 다운되었는지 육안으로 관찰할 수 없다는 점이다.

그래서 앱과 API 사이에 서비스 관리 센터를 추가하면 API는 서비스 관리 센터 등록 정보와 같습니다. API에는 고유 식별자가 있습니다. API가 변경되면 서비스 관리 센터에 알리며, 서비스 관리 센터는 정기적으로 서비스 관리 센터로부터 최신 API 정보를 얻기 위해 해당 앱이나 앱에 알림을 보냅니다.

eureka는 그런 서비스 관리 센터를 위한 것입니다. 아래는 제가 직접 이해한 내용을 바탕으로 그린 ​​그림입니다.

SpringCloud의 마이크로서비스 배포에 대한 자세한 설명

다음은 공식 아키텍처 다이어그램입니다

SpringCloud의 마이크로서비스 배포에 대한 자세한 설명

1.Application Service는 서비스 공급자/api

2.Application Client는 서비스 소비자/app

3과 동일합니다. 원격 호출은 실제로 httpClient, RestTemplate

4.us-east-1 Eureka 클러스터 서비스

5.us-east-1c, us-east-1d, us-east-1e와 같은 서비스 사용을 구현하기 위한 것입니다. 특정 유레카

Eureka:

  1. 는 순수 서블릿 애플리케이션으로, war 패키지에 내장되어 배포되어야 합니다.

  2. Jersey 프레임워크를 사용하여 자체 RESTful HTTP 인터페이스 구현

  3. 피어 동기화 및 서비스 등록은 모두 HTTP 프로토콜을 통해 구현됩니다

  4. 예약된 작업(하트비트 전송, 만료된 서비스 정기적 정리, 노드 동기화 등)은 JDK와 함께 제공되는 타이머를 통해 구현됩니다

  5. 메모리 캐시 Google의 guava 패키지를 사용하여 구현되었습니다

유레카 클러스터 구축

유레카와 유사한 기능으로는 Zookeeper, etcd 등이 있습니다. 스프링 부트에는 유레카가 통합되어 있으므로 스프링 부트처럼 환경을 설정하고 배포 및 실행할 수 있습니다.

윈도우 10에서 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, 이는 이것이 서버 서비스임을 나타냅니다.

구성 파일 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의 주소와 포트를 입력합니다. 이는 유레카 서비스 3개 01, 02, 03을 의미합니다. 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으로 문의하시기 바랍니다. 삭제