wordpress 获取域名/中山seo

wordpress 获取域名,中山seo,上海专业做网站较好的公司,webapp开发文章目录 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.mzph.cn/web/72284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络-网络规划与设计

基本流程 需求分析—》通信规范分析—》逻辑网络设计—》物理网络设计—》实施阶段 需求分析&#xff1a; 确定需求&#xff0c;包括&#xff1a;业务需求、用户需求、应用需求、计算机平台需求、网络通信需求等。 产物&#xff1a;需求规范 通信规范分析&#xff1a; 现有…

《AI浪潮中的璀璨新星:Meta Llama、Ollama与DeepSeek的深度剖析》:此文为AI自动生成

《AI浪潮中的璀璨新星&#xff1a;Meta Llama、Ollama与DeepSeek的深度剖析》&#xff1a;此文为AI自动生成 引言&#xff1a;AI 大模型的群雄逐鹿时代 在科技飞速发展的当下&#xff0c;AI 大模型领域已成为全球瞩目的焦点&#xff0c;竞争激烈程度堪称白热化。从 OpenAI 推出…

DeepSeek linux服务器(CentOS)部署命令笔记

Linux&#xff08;CentOS&#xff09;FinalShellOllama远程访问&#xff0c;本地部署deepseek 自备CentOS服务器&#xff0c;并且已经使用FinalShell连接到服务器 一、准备工作 1.更新服务器 apt-get update-y 2.下载Ollama curl -fsSL https://ollama.com/install.sh | …

C#通过API接口返回流式响应内容---分块编码方式

1、背景 上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE&#xff08;Server Send Event&#xff09;方式&#xff0c;由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现 2、效果 3、具体代码 3.1 API端实现 [HttpGet] public async Task Chu…

SSL 原理及实验

引言 为了实现远程办公或者远程客户访问内网的资源 &#xff08;1&#xff09;回顾历史&#xff1a; 起初先出现SSL(Secure Sockets Layer&#xff09;&#xff0d;安全套接层协议。 美国网景Netscape公司1994年研发&#xff0c;介于传输层TCP协议和应用层协议之间的一种协议…

UE5.5 Niagara发射器更新属性

发射器属性 在 Niagara 里&#xff0c;Emitter 负责控制粒子生成的规则和行为。不同的 Emitter 属性决定了如何发射粒子、粒子如何模拟、计算方式等。 发射器 本地空间&#xff08;Local Space&#xff09; 控制粒子是否跟随发射器&#xff08;Emitter&#xff09;移动。 ✅…

各省水资源平台 水资源遥测终端机都用什么协议

各个省水资源平台 水资源遥测终端机 的建设大部分从2012年开始启动&#xff0c;经过多年建设&#xff0c;基本都已经形成了稳定的通讯要求&#xff1b;河北瑾航科技 遥测终端机&#xff0c;兼容了大部分省市的通讯协议&#xff0c;如果需要&#xff0c;可以咨询和互相学习&…

使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录 抽烟检测的运用 1. 安全监控 (1) 公共场所禁烟监管 (2) 工业安全 2. 智能城市与执法 (1) 城市违章吸烟检测 (2) 无人值守管理 3. 健康管理与医疗 (1) 吸烟习惯分析 (2) 远程监护 4. AI 监控与商业分析 (1) 保险行业 (2) 商场营销 5. 技术实现 (1) 计算机视…

WPF窗口读取、显示、修改、另存excel文件——CAD c#二次开发

效果如下&#xff1a; using System.Data; using System.IO; using System.Windows; using Microsoft.Win32; using ExcelDataReader; using System.Text; using ClosedXML.Excel;namespace IfoxDemo {public partial class SimpleWindow : Window{public SimpleWindow(){Initi…

HarmonyOS NEXT - 电商App实例三( 网络请求axios)

使用axios开发网络请求是一个非常常见的任务&#xff0c;尤其是Web前端开发者&#xff0c;对它非常熟悉。axios是一个基于Promise的HTTP客户端&#xff0c;支持浏览器和Node.js环境&#xff0c;使用简单且功能强大。 在harmonyOS中&#xff0c;如果想使用axios&#xff0c;可以…

Unity进阶课程【二】Mask 组件的使用 UI遮罩效果以及透明抠图效果

Unity组件讲解 Mask 时隔多年&#xff0c;今天咱们继续进阶课程&#xff0c;这几年变化很大&#xff0c;但是一直还是从事Unity行业&#xff0c;行业虽难&#xff0c;依旧坚持&#xff0c;以后会养成习惯&#xff0c;定期更新&#xff0c;希望小伙伴们监督&#xff0c;有想学习…

汽车无钥匙启动系统不使用传统机械钥匙启动汽车

汽车无钥匙启动系统 定义 汽车无钥匙启动系统&#xff08;Keyless Start System&#xff09;&#xff0c;启动车辆时不用掏拧钥匙&#xff0c;只需把钥匙放在包内或口袋里&#xff0c;按下车内按键或拧动导板即可使发动机点火。它无需插入钥匙&#xff0c;通过点按按键或旋转…

【Python】Python 3.11安装教程

一、Python 3.11安装包下载 1. Python 3.11下载与安装 Download Python | Python.org 下载完成包含以下文件&#xff1a; 二、python3.11安装步骤 1.右键以管理员身份运行安装程序。 2.勾选【Add Python…】然后点击【Customize…】。 3.页面点击【Next】。 4.勾选【Install …

如何处理PHP中的编码问题

如何处理PHP中的编码问题 在PHP开发过程中&#xff0c;编码问题是一个常见且棘手的问题。无论是处理用户输入、数据库交互&#xff0c;还是与外部API通信&#xff0c;编码问题都可能导致数据乱码、解析错误甚至安全漏洞。本文将深入探讨PHP中的编码问题&#xff0c;并提供一些…

【毕业论文格式】word分页符后的标题段前间距消失

文章目录 【问题描述】 分页符之后的段落开头&#xff0c;明明设置了标题有段前段后间距&#xff0c;但是没有显示间距&#xff1a; 【解决办法】 选中标题&#xff0c;选择边框 3. 选择段前间距&#xff0c;1~31磅的一个数 结果

论文调研 | 一些开源的AI代码生成模型调研及总结【更新于250313】

本文主要介绍主流代码生成模型&#xff0c;总结了基于代码生成的大语言模型&#xff0c;按照时间顺序排列。 在了解代码大语言模型之前&#xff0c;需要了解代码相关子任务 代码生成 文本生成代码(Text to code):根据自然语言描述生成代码 重构代码&#xff08;Refactoring …

3DS模拟器使用(pc+安卓)+金手指+存档互传

1、引言 3ds模拟器已经能够在手机端近乎完美模拟了&#xff0c;那么多的3ds游戏&#xff0c;比玩手机游戏舒服多了。 本人是精灵宝可梦的老玩家&#xff0c;从第一世代就一直在玩&#xff0c;刚耍完NDS的第五世代&#xff0c;黑白系列。现在到宝可梦XY了&#xff0c;需要在3d…

Java EE Web环境安装

Java EE Web环境安装 一、JDK安装与测试&#xff08;Windows环境&#xff09; 1. 安装JDK 官网下载&#xff1a;Oracle JDK&#xff08;选择Windows x64 Installer&#xff09;双击安装包&#xff0c;按向导完成安装 ​ 2. 环境变量配置 右键【此电脑】→【属性】→【高级…

探索CSS魔法:3D翻转与渐变光效的结合

随着前端技术的不断发展&#xff0c;CSS不再仅仅局限于样式设计&#xff0c;它也成为了实现富有互动性的动画和特效的强大工具。本篇文章将向大家展示如何利用CSS的3D变换和渐变光效&#xff0c;打造一张“神秘卡片”&#xff0c;通过简单的代码实现炫酷的视觉效果。 1. 初识神…

C++ STL 深度解析:vector 的全面指南与进阶技巧

一、底层架构深度剖析 1.1 内存管理机制 vector 通过三个指针实现动态内存管理&#xff1a; _start&#xff1a;指向分配内存的首元素&#xff08;begin()返回值&#xff09;_finish&#xff1a;指向最后一个元素的下一个位置&#xff08;end()返回值&#xff09;_end_of_st…