当前位置: 首页 > wzjs >正文

江北网站建设价格专业做加盟推广的公司

江北网站建设价格,专业做加盟推广的公司,百度云做网站,家庭nas可以做网站服务器文章目录 SpringCloudSpringCloud 概述集群和分布式集群和分布式的区别和联系 微服务什么是微服务?分布式架构和微服务架构的区别微服务的优缺点?拆分微服务原则 什么是 SpringCloud ?核心功能与组件 工程搭建父项目的 pom 文件 注册中心Rest…

文章目录

  • SpringCloud
    • SpringCloud 概述
      • 集群和分布式
        • 集群和分布式的区别和联系
      • 微服务
        • 什么是微服务?
        • 分布式架构和微服务架构的区别
        • 微服务的优缺点?
        • 拆分微服务原则
      • 什么是 SpringCloud ?
        • 核心功能与组件
    • 工程搭建
      • 父项目的 pom 文件
    • 注册中心
      • RestTemplate
      • 注册中心介绍
      • CAP 理论
      • Eureka
        • 添加依赖
        • 配置文件
        • 启动类
        • 查看
        • 服务注册
          • 添加依赖
          • 配置文件
          • 查看
        • 服务发现
          • 依赖、配置
          • 修改代码
        • Eureka 和 Zookeeper 区别
    • 负载均衡
      • 多次在不同的端口号上开启同一个服务
      • 出现的问题
      • 解决问题
      • 负载均衡正式介绍
        • 什么是负载均衡
        • 负载均衡的一些实现
          • 服务端负载均衡
          • 客户端负载均衡
        • SpringCloud LoadBalancer
          • 负载均衡策略
          • LoadBalancer 原理
            • 随机选择策略
            • 轮询策略
          • 服务部署

SpringCloud

SpringCloud 概述

集群和分布式

集群:是将一个系统完整的部署到多个服务器上,每个服务器都能提供系统的所有服务,多个服务器通过负载均衡调度完成任务,每个服务器称为集群的节点。

分布式:是将一个系统拆分成多个子系统,多个子系统部署在多个服务器上,多个服务器上的子系统协同合作完成一个特定任务。

集群和分布式的区别和联系
  1. 集群是多个计算机做同样的事情,分布式是多个计算机做不同的事。
  2. 集群的每一个节点的功能是相同的,并且是可以替代的。分布式也是多个节点组成的系统,但是每个节点完成的任务是不同的,一个节点出现问题,这个业务就无法访问了。
  3. 分布式和集群在实践中,很多时候都是相互配合使用的。比如分布式的某一个节点,可能由一个集群来代替。分布式架构大多数是建立在集群上的。所以实际的分布式架构中并不会把分布式和集群单独区分,而是统称:分布式架构。

微服务

什么是微服务?

微服务是一种经过良好架构设计的分布式架构方案。

一个服务只对应一个单一的功能,只做一件事,这个服务可以单独部署运行。

分布式架构和微服务架构的区别

分布式:服务拆分,拆了就行。

微服务:指非常微小的服务,更细粒度的垂直拆分,通常指不能再拆的服务。

分布式架构侧重于压力的分散,强调的是服务的分散化,微服务侧重于能力的分散,更强调服务的专业化和精细分工。

微服务的优缺点?

优点:

image-20250311173842098

缺点:

image-20250311173920969

拆分微服务原则
  1. 单一职责原则

    单一职责原则原本是面向对象程序设计中的一个基本原则,它指的是一个类应该专注于单一功能。

    在微服务架构中,一个微服务也应该只负责一个功能或业务领域,每个服务应该有清晰的定义和边界,只关注自己的特定业务领域。

  2. 服务自治

    服务自治是指每个微服务都应该具备高度自治的能力,即每个服务要能做到独立开发,独立测试, 独立构建, 独立部署,独立运行。

  3. 单向依赖

    微服务之间需要做到单向依赖,严禁循环依赖,双向依赖。

    image-20250311174451006

    如果一些场景确实无法避免循环依赖或者双向依赖,,可以考虑使用消息队列等其他方式来实现。

什么是 SpringCloud ?

Spring Cloud 是一套基于 Spring Boot 的微服务开发工具集,用于简化分布式系统(如微服务架构)的构建、部署和管理。它整合了多种开源组件,提供了一站式解决方案,帮助开发者快速实现服务治理、配置管理、负载均衡、熔断降级等分布式系统中的常见问题。

简单的说,Spring Cloud 就是分布式微服务架构的一站式解决方案。

核心功能与组件
  1. 服务注册与发现
    • 组件:EurekaNacosConsul
    • 功能:服务自动注册到注册中心,并通过服务名实现动态发现,避免硬编码服务地址。
  2. 负载均衡
    • 组件:RibbonLoadBalancer
    • 功能:在多个服务实例间分配请求,支持轮询、随机等策略。
  3. 服务调用
    • 组件:OpenFeign
    • 功能:声明式的 HTTP 客户端,简化服务间的 RESTful 调用。
  4. 熔断与容错
    • 组件:HystrixResilience4jSentinel
    • 功能:防止服务雪崩,提供降级逻辑和故障隔离。
  5. 配置中心
    • 组件:Spring Cloud ConfigNacos
    • 功能:集中管理配置文件,支持动态更新。
  6. API 网关
    • 组件:Spring Cloud GatewayZuul
    • 功能:统一入口,处理路由、鉴权、限流等跨服务功能。
  7. 分布式链路追踪
    • 组件:Sleuth + Zipkin
    • 功能:追踪请求在微服务间的调用路径,便于排查问题。

工程搭建

父项目的 pom 文件

指定父项目的打包方式:

image-20250311175319332

添加依赖:

image-20250311175027099

子项目被创建时,父项目的 pom 文件中会自动添加

image-20250311175514057

上面的代码表示这里有两个子项目(模块),分别是 order-service 和 product-service 。

注册中心

RestTemplate

RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它是一个同步的 REST API 客户端,提供了常见的 REST 请求方案的模版。

在项目中,当我们需要远程调用一个 HTTP 接口时,我们经常会用到 RestTemplate 这个类。这个类是 Spring 框架提供的一个工具类。

定义 RestTemplate

@Configuration
public class BeanConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

使用 RestTemplate

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);// 通过 RestTemplate 从指定 URL 获取 ProductInfo 对象String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

在前面的示例中 URL 是写死的。写死这个事情做的不好,如果服务器的 IP 发生变化,我们还得把所有 IP 都修改,太麻烦了,而且没有技术含量。

String url = "http://127.0.0.1:9090/product/";

注册中心介绍

有没有什么办法来解决这个问题呢?

我们可以这样做:

当服务 启动/变更 时, 向注册中⼼报道。注册中⼼记录应⽤和 IP 的关系。

调⽤⽅调⽤时,先去注册中⼼获取服务⽅的 IP,再去服务⽅进⾏调⽤。

image-20250311212947467

image-20250311213409451

CAP 理论

image-20250311213758583

  • 一致性(C):CAP 理论中的一致性,指的是强一致性。所有节点在同一时间具有相同的数据。

    image-20250311214959974

    强一致性:主库和从库不论何时,服务器对外提供的服务都是一致的。

    弱一致性:随着时间的推移,主库和从库最终达到了一致性。

  • 可用性(A):保证每个请求都有响应。

  • 分区容错性(P):当出现网络分区后,系统仍然能够对外提供服务。

    网络分区:指分布式系统中,由于网络故障导致集群中的节点被分割成多个孤立的子集,子集之间的节点无法正常通信,但子集内部的节点仍然可以正常通信。这种现象也被称为“脑裂”(Split-Brain)。

    举个例子

    假设有一个分布式系统,由 5 个节点(A、B、C、D、E)组成,它们之间通过网络通信。如果由于网络故障,节点 A 和 B 之间的网络断开,那么可能会形成两个分区:

    • 分区 1:节点 A、B
    • 分区 2:节点 C、D、E

    此时,分区 1 和分区 2 之间的节点无法通信,但分区内部的节点仍然可以正常通信。

在分布式系统中,系统间的⽹络不能100%保证健康, 服务⼜必须对外保证服务. 因此 分区容错性(P) 不可避免. 那就只能在 C 和 A 中选择⼀个. 也就是 CP 或者 AP 架构。

正常情况:

image-20250311215348627

网络异常:

image-20250311215423635

CP架构:为了保证分布式系统对外的数据⼀致性,于是选择不返回任何数据。

AP架构:为了保证分布式系统的可⽤性,节点2返回V0版本的数据(即使这个数据不正确)。

关于CAP的更多信息,可以看看这篇文章:一文看懂|分布式系统之CAP理论-腾讯云开发者社区-腾讯云

Eureka

添加依赖
 <!--  给客户端用  --><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies><!--  给服务器用  -->
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><!--  借助 Maven 打包  --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
配置文件
# Eureka相关配置
# Eureka 服务
server:port: 10010
spring:application:# 这个应用的名称name: eureka-server
eureka:instance:# 主机的名称hostname: localhostclient:# 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为falsefetch-registry: false# 表示是否将自己注册到Eureka Server,默认为true.register-with-eureka: false service-url:# 设置Eureka Server的地址,查询服务和注册服务都需要依赖这个地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类
@EnableEurekaServer  // 开启 Eureka 的功能
@SpringBootApplication
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}
查看
http://127.0.0.1:10010/

image-20250314164624808

服务注册
添加依赖
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
配置文件
spring:application:# 配置应用名称name: product-service#Eureka Client
eureka:client:service-url:# 注册到哪里 / 从哪里拿相关信息defaultZone: http://127.0.0.1:10010/eureka/
查看
http://127.0.0.1:10010/

image-20250314164722794

服务发现
依赖、配置

同服务注册。

修改代码
import org.springframework.cloud.client.discovery.DiscoveryClient;   
// 注意不要引错包@Autowiredprivate DiscoveryClient discoveryClient;// 从 Eureka 中获取服务列表,括号内写应用名称List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();// 替换之前写死的 url String url = uri + "/product/" + orderInfo.getProductId();
Eureka 和 Zookeeper 区别

Eureka 和 Zookeeper 都是用于服务注册和服务发现的工具,区别如下:

  1. Eureka 基于 AP 原则,保证高可用。Zookeeper 基于 CP 原则,保证数据一致性。
  2. Eureka 每个节点都是均等的,Zookeeper 的节点区分 Leader 和 Follower 或 Observer,如果 Zookeeper 的 Leader 发生故障时,需要重新选举,选举过程集群会有短暂时间的不可用。

负载均衡

多次在不同的端口号上开启同一个服务

image-20250314172405488

点击 Services 并添加应用

image-20250314172548516

选择 Application

image-20250314172632852

复制你要多开的服务

image-20250314172710731

设置端口号,设置完毕后点击 Apply。

image-20250314172839615

可以看到,已经配置好了。

image-20250314173002148

出现的问题

当我们进行多次访问时,每次的 discoveryClient.getInstances(“product-service”); 拿到的列表是不固定的。

    public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);// 从 Eureka 中获取服务列表List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();// 替换之前写死的 urlString url = uri + "/product/" + orderInfo.getProductId();log.info("远程调用 url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}

image-20250314173928563

显然这并不是很合理。

解决问题

假设我们想让请求平均分配到每个端口上。可以使用以下方法:

image-20250314174244230

修改代码:

package com.demo.order.service;import com.demo.order.mapper.OrderMapper;
import com.demo.order.model.OrderInfo;
import com.demo.order.model.ProductInfo;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;/*** @author hanzishuai* @date 2025/03/07 19:19* @Description*/
@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;// 计数器private AtomicInteger count = new AtomicInteger(1);// 将实例提取出来private List<ServiceInstance> instances;@PostConstructpublic void init() {// 从 Eureka 中获取服务列表instances = discoveryClient.getInstances("product-service");}// 这是之前的写法:    
//        public OrderInfo selectOrderById(Integer orderId) {
//        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
//        String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();
//    
//        // 从 Eureka 中获取服务列表,这里每次请求拿到的 instances 是不固定的 
//        List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
//        String uri = instances.get(0).getUri().toString();
//    
//        // 替换之前写死的 url
//        String url = uri + "/product/" + orderInfo.getProductId();
//        log.info("远程调用 url:{}", url);
//        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
//        orderInfo.setProductInfo(productInfo);
//        return orderInfo;
//    }public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);// 实现平均分配int index = count.getAndIncrement() % instances.size();String uri = instances.get(index).getUri().toString();String url = uri + "/product/" + orderInfo.getProductId();log.info("远程调用 url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

但是上述写法会带来一个新的问题:当实例发生变化,这里的服务并不能实时的感知到。

不要较真,在这里只是为了演示一下。

更改后的效果:

image-20250314180245882

负载均衡正式介绍

什么是负载均衡

负载均衡用来在多个机器或者其他资源中,按照一定的规则合理分配负载。

比如说,有很多请求和很多服务器,负载均衡就是把这些请求合理的分配到各个服务器上。

负载均衡的一些实现
服务端负载均衡

服务端负载均衡就是在服务端进行负载均衡算法的分配。

以 Nginx 为例,请求先到达 Nginx 负载均衡器,然后通过负载均衡算法,在多个服务器之间选一个进行访问。

image-20250314182324386
客户端负载均衡

服务端负载均衡就是在客户端进行负载均衡算法的分配。

以 SpringCloud 的 Ribbon 为例,请求发送到客户端,客户端从注册中心获取服务器列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问。

image-20250314183108271
SpringCloud LoadBalancer

加上 @LoadBalanced 注解

@Configuration
public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

修改代码

    public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);// 修改前// String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();// 修改后String url = "http://product-service/product/" + orderInfo.getProductId();log.info("远程调用 url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}

效果:

image-20250314203553542

image-20250314203658809

image-20250314203605370

负载均衡策略

SpringCloud LoadBalancer 仅支持两种负载均衡策略:

  1. 轮询策略: 指服务器轮流处理用户的请求.
  2. 随机选择: 随机选择一个后端服务器来处理请求.

自定义负载均衡策略

public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

使用方法:

  1. 需要在关联负载均衡策略的配置类上添加 @LoadBalancerClient 或者 @LoadBalancerClients 注解.

    // name 表示要对那个服务生效, configuration 表示你采取的负载均衡策略是什么.
    @LoadBalancerClient(name = "product-service",configuration = CustomLoadBalancerConfiguration.class)
    @Configuration
    public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
    }
    
  2. 自定义负载均衡策略的配置类(如 CustomLoadBalancerConfiguration)上不能使用 @Configuration 注解.

    原因: 如果 CustomLoadBalancerConfiguration 类被标记为 @Configuration,并且位于主应用程序组件扫描的路径下,它会被 Spring 自动加载为一个配置类。而当通过 @LoadBalancerClient 的 configuration 属性引用它时,可能会导致 Spring 尝试再次加载它,从而产生冲突或重复的 bean 定义。

  3. 自定义负载均衡策略的配置类(如 CustomLoadBalancerConfiguration)必须能被 Spring 容器发现。

是不是感觉与第三条第二条有矛盾?

  • 在之前的回答中提到,CustomLoadBalancerConfiguration 不能添加 @Configuration 注解,这是为了避免被 Spring 自动扫描到后重复加载。
  • 但同时又需要确保该类能被 Spring 容器发现,这里的矛盾需要通过以下方式解决:
    • 通过 @LoadBalancerClient(configuration = ...) 显式引用该类,而不是依赖组件扫描。上面的 BeanConfig 采用的就是这种方法。
    • 确保 CustomLoadBalancerConfiguration 不在主应用的扫描范围内,但能被 @LoadBalancerClient 正确引用。
LoadBalancer 原理

tip: 按 Ctrl + alt + ← 或者 → 可以快速定位上/下次查看的位置

在 LoadBalancerInterceptor 中有一个 intercept 方法:

	@Overridepublic ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {// 拿到 uri final URI originalUri = request.getURI();// 拿到 hostString serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);return this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));}

它会拦截所有的请求。

它做了三件事:

  1. 拿到 uri,也就是 http://product-service/product/1001
  2. 拿到 host,也就是 product-service
  3. 执行

接下来具体看看 this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution))它干了什么。

   public <T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException {String hint = this.getHint(serviceId);LoadBalancerRequestAdapter<T, TimedRequestContext> lbRequest = new LoadBalancerRequestAdapter(request, this.buildRequestContext(request, hint));Set<LoadBalancerLifecycle> supportedLifecycleProcessors = this.getSupportedLifecycleProcessors(serviceId);supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onStart(lbRequest);});// 通过 choose 方法返回了一个应用ServiceInstance serviceInstance = this.choose(serviceId, lbRequest);if (serviceInstance == null) {supportedLifecycleProcessors.forEach((lifecycle) -> {lifecycle.onComplete(new CompletionContext(Status.DISCARD, lbRequest, new EmptyResponse()));});throw new IllegalStateException("No instances available for " + serviceId);} else {return this.execute(serviceId, serviceInstance, lbRequest);}}

接下来看一下 choose 方法

    public <T> ServiceInstance choose(String serviceId, Request<T> request) {// 根据应用名称获取负载均衡策略ReactiveLoadBalancer<ServiceInstance> loadBalancer = this.loadBalancerClientFactory.getInstance(serviceId);if (loadBalancer == null) {return null;} else {// 如果 loadBalancer 不为空,这里又进行了一次选择Response<ServiceInstance> loadBalancerResponse = (Response)Mono.from(loadBalancer.choose(request)).block();return loadBalancerResponse == null ? null : (ServiceInstance)loadBalancerResponse.getServer();}}

如果 loadBalancer 不为空,这里又进行了一次选择接下来进入 Response<ServiceInstance> loadBalancerResponse = (Response)Mono.from(loadBalancer.choose(request)).block() 中的 choose 看看,

可以看到它有两个实现,一个是RandomLoadBalancer,一个是RoundRobinLoadBalancer

image-20250314222100838

随机选择策略

先来看一下 RandomLoadBalancer

    public Mono<Response<ServiceInstance>> choose(Request request) {// 做了一些处理ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);// 根据请求获取到服务列表return supplier.get(request).next().map((serviceInstances) -> {// 对服务列表进行处理return this.processInstanceResponse(supplier, serviceInstances);});}

进入 processInstanceResponse 看一下

    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, List<ServiceInstance> serviceInstances) {Response<ServiceInstance> serviceInstanceResponse = this.getInstanceResponse(serviceInstances);if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());}return serviceInstanceResponse;}

getInstanceResponse 看一下

    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {if (instances.isEmpty()) {if (log.isWarnEnabled()) {log.warn("No servers available for service: " + this.serviceId);}return new EmptyResponse();} else {// 生成随机数int index = ThreadLocalRandom.current().nextInt(instances.size());// 根据生成的随机数,在服务列表中选择ServiceInstance instance = (ServiceInstance)instances.get(index);// 进行下一步的处理return new DefaultResponse(instance);}}
轮询策略

进入RoundRobinLoadBalancer

image-20250314223558314

    public Mono<Response<ServiceInstance>> choose(Request request) {ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);return supplier.get(request).next().map((serviceInstances) -> {return this.processInstanceResponse(supplier, serviceInstances);});}

进入 processInstanceResponse

    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, List<ServiceInstance> serviceInstances) {Response<ServiceInstance> serviceInstanceResponse = this.getInstanceResponse(serviceInstances);if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());}return serviceInstanceResponse;}

进入 getInstanceResponse

    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {if (instances.isEmpty()) {if (log.isWarnEnabled()) {log.warn("No servers available for service: " + this.serviceId);}return new EmptyResponse();} else if (instances.size() == 1) {return new DefaultResponse((ServiceInstance)instances.get(0));} else {// 计数器int pos = this.position.incrementAndGet() & 2147483647;// 通过计数器 % instances.size() 来拿到坐标ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());return new DefaultResponse(instance);}}
服务部署

参考 博客系统笔记总结 2( Linux 相关) 中的部署 Web 项目到 Linux


本文到这里就结束啦~

在这里插入图片描述

http://www.dtcms.com/wzjs/344199.html

相关文章:

  • 广州微信网站设计制作站长工具seo综合查询
  • 百度推广负责做网站吗营销网络推广
  • 高端it网站建设网络整合营销4i原则是指
  • 厦门市建设工程造价协会官方网站长沙百度快速优化排名
  • 电脑课做网站所需的软件百度链接提交工具
  • 网站开发公司哪里济南兴田德润实惠吗营销的手段和方法
  • 务分销系统关键词优化骗局
  • 做网站前台需要什么软件seo优化服务是什么意思
  • 微信公众号网页制作教程网站优化公司推荐
  • 服务好的网站建设网站友情链接的好处
  • 如何在百度做网站推广页面优化的方法
  • 网站备案信息代码淘宝摄影培训推荐
  • 做图素材网站哪个好杭州优化关键词
  • 网站框架代码舆情监控
  • 厦门 网站开发百度指数排名
  • 室内设计多久能学出来seo优化排名营销
  • 上海网络营销的企业重庆高端seo
  • 信阳网站开发公司电话如何免费注册网站平台
  • 南昌网站排名semi
  • 网站做网络营销的效果东莞网站建设推广品众
  • 网站 框架图销售推广的方法都有哪些
  • 大连网站制作最好的公司apple日本网站
  • 网站建设公司宣传网络推广发展
  • 域名备案需要哪些材料广东seo点击排名软件哪里好
  • 佛山网站建设佛山网络推广种子搜索神器下载
  • 网站建设及维护推广合同seo建站公司
  • 包头市建设工程质量监督站网站想要网站推广版
  • 长沙人才市场招聘信息厦门网站seo哪家好
  • 提供网站建设设计seo是什么意思
  • 做网站可以找设计公司吗域名权重