IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring Cloud 学习笔记(持续更新) -> 正文阅读

[Java知识库]Spring Cloud 学习笔记(持续更新)

1 微服务

1.1 spring cloud 是什么

  • 他是一套分布式框架集合,基于 spring boot 开发的。
  • 他是一种规范。
  • 将不同公司生产的不同组件以 spring boot 的风格来集成。
  • 这样的话,开发者就不用关心组件之间的整合,开箱即用,需要哪个组件直接用 spring boot 整合进来。

1.2 什么是 spring cloud alibaba

  • 在 spring cloud 规范下出现的具体一套解决方案。

2 eureka 注册中心

2.1如何在多个微服务中发送远程 http 请求

2.1.1 首先我们在配置类中向 spring 容器注入 RestTemplate 对象的 Bean:

  • 这里我们直接在启动类中注册,因为启动类也是一个配置类
package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建 RestTemplate 并注入 Spring 容器中
     * @return RestTemplate
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2.1.2 我们接着修改 service 层中的服务信息

package cn.itcast.order.service;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    // 自动装配 RestTemplate
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);

        // 2.利用 RestTemplate 的实例来向别的服务发送 http 远程调用,这里我们查询用户
        // 2.1 远程请求的 url 路径
        String url = "http://localhost:8081/user/" + order.getUserId();
        // 2.2 发送 http 请求
        User user = restTemplate.getForObject(url, User.class);

        // 3.封装 user 到 order
        order.setUser(user);

        // 4.返回
        return order;
    }
}

2.1.3 最后启动两个不同的服务即可

2.2 搭建 eureka 服务

2.2.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <dependencies>

        <!-- eureka服务端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

    </dependencies>

</project>

2.2.2 在启动类上添加 eureka 自动装配注解 @EnableEurekaServer

package cn.itcast.eureka;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

2.2.3 新建 application.yml 配置文件配置 eureka 如下信息

#eureka服务端口
server:
  port: 10006

#以下两步都是为了服务注册才配置的
#eureka服务名称
spring:
  application:
    name: eurekaserver

#eureka地址信息:eureka自己也注册进来,方便之后集群部署注册中心之间的通信。
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10006/eureka

2.3 eureka 服务注册

2.3.1 引入如下依赖

<!-- eureka-client -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.3.2 在该 module 的 application.yml 下注册 eureka 服务

server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: userservice #注册这个module的服务名称

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10006/eureka

2.3.3 注册多个相同的服务

  • 在 idea 中我们在左下角 service 中可以看到服务列表,我们在服务列表中可以copy一份想要增加的服务。。
  • 千万不要忘记更改端口号为未使用过的端口号。

右键 --> copy configuration --> 改名 --> environment --> VMoptions 中输入 -Dserver.port=端口号。

2.3.4 服务发现并且负载均衡

  • 引入 eureka-client 依赖。
  • 在当前 moudule 的 application.yml 中配置 eureka 地址。
  • 给我们的 RestTemplate 添加 @LoadBalanced 注解让 eureka 自动进行负载均衡。
package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建 RestTemplate 并注入 Spring 容器中
     * @return RestTemplate
     */
    @Bean
    
    // ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    @LoadBalanced
    // ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

  • 最后将服务提供者的服务名称远程调用
    • 如:UserService 这个 Moudule 的远程调用服务名称在这个 Moudule 中的 application.yml 文件中配置了,叫做 userservice。
package cn.itcast.order.service;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);

        // 2.利用 RestTemplate 的实例来向别的服务发送 http 远程调用,这里我们查询用户
        // 2.1 远程请求的 url 路径
        
        // ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        String url = "http://userservice/user/" + order.getUserId(); 
        // ~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        
        // 2.2 发送 http 请求
        User user = restTemplate.getForObject(url, User.class);

        // 3.封装 user 到 order
        order.setUser(user);

        // 4.返回
        return order;
    }
}

3 Ribbon 负载均衡

3.1 源码理解

3.1.1 @LoadBalanced 注解:标记的方法发起的请求要被 robbin 拦截去做负载均衡。

3.1.2 LoadBalancerInterceptor 核心类实现 ClientHttpRequestInterceptor 接口。

3.1.3 ClientHttpRequestInterceptor 接口是客户端http请求拦截器。

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.client.loadbalancer;

import java.io.IOException;
import java.net.URI;

import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;

/**
 * @author Spencer Gibb
 * @author Dave Syer
 * @author Ryan Baxter
 * @author William Tran
 */
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

	private LoadBalancerClient loadBalancer;

	private LoadBalancerRequestFactory requestFactory;

	public LoadBalancerInterceptor(LoadBalancerClient loadBalancer,
			LoadBalancerRequestFactory requestFactory) {
		this.loadBalancer = loadBalancer;
		this.requestFactory = requestFactory;
	}

	public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
		// for backwards compatibility
		this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
	}

	@Override
	public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
			final ClientHttpRequestExecution execution) throws IOException {
		final URI originalUri = request.getURI();
		String serviceName = originalUri.getHost();
        
        // 走到这一步就去找eureka拉取服务,这里是获得远程调用服务名称。
		Assert.state(serviceName != null,
				"Request URI does not contain a valid hostname: " + originalUri);
        
        
        // 将服务名称传给 RobbinLoadBalancerClient 的对象 loadBalancer 来执行
		return this.loadBalancer.execute(serviceName,
				this.requestFactory.createRequest(request, body, execution));
	}

}

3.1.4 在 RibbonLoadBalancerClient 中的 execute 方法中进行如下操作

	/**
	 * New: Execute a request by selecting server using a 'key'. The hint will have to be
	 * the last parameter to not mess with the `execute(serviceId, ServiceInstance,
	 * request)` method. This somewhat breaks the fluent coding style when using a lambda
	 * to define the LoadBalancerRequest.
	 * @param <T> returned request execution result type
	 * @param serviceId id of the service to execute the request to
	 * @param request to be executed
	 * @param hint used to choose appropriate {@link Server} instance
	 * @return request execution result
	 * @throws IOException executing the request may result in an {@link IOException}
	 */
	public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
			throws IOException {
        // 通过 serviceId 也就是我们远程调用服务的名称,找 eureka 拉取服务列表
		ILoadBalancer loadBalancer = getLoadBalancer(serviceId); 
        // 这行代码就是在做负载均衡
		Server server = getServer(loadBalancer, hint);
		if (server == null) {
			throw new IllegalStateException("No instances available for " + serviceId);
		}
		RibbonServer ribbonServer = new RibbonServer(serviceId, server,
				isSecure(server, serviceId),
				serverIntrospector(serviceId).getMetadata(server));

		return execute(serviceId, ribbonServer, request);
	}

我们此时可以在调试的 loadBalancer 对象中查看到我们注册在 eureka 上的服务:

this = {RibbonLoadBalancerClient@9301} 
serviceId = "userservice"
request = {LoadBalancerRequestFactory$lambda@9355} 
 balancers = {ConcurrentHashMap@9796}  size = 0
 triggeringLoad = null
 triggeringBlackoutPercentage = null
 isSecure = false
 useTunnel = false
 serverListUpdateInProgress = {AtomicBoolean@9797} "false"
 serverListImpl = {DomainExtractingServerList@9798} 
 filter = {ZonePreferenceServerListFilter@9799} "ZonePreferenceServerListFilter{zone='defaultZone'}"
 updateAction = {DynamicServerListLoadBalancer$1@9800} 
 serverListUpdater = {PollingServerListUpdater@9801} 
 rule = {ZoneAvoidanceRule@9802} 
 pingStrategy = {BaseLoadBalancer$SerialPingStrategy@9803} 
 ping = {NIWSDiscoveryPing@9804} 
 allServerList = {ArrayList@9805}  size = 2
 upServerList = {ArrayList@9806}  size = 2
  // 在这
  0 = {DomainExtractingServer@9826} "LAPTOP-EM069R1M:8082" 
  1 = {DomainExtractingServer@9827} "LAPTOP-EM069R1M:8081"

3.1.5 负载均衡实现

RobbinLoadBalancerClient——> protected Server getServer(ILoadBalancer loadBalancer, Object hint) 方法 ——>

ZoneAwareLoadBalancer——> public Server chooseServer(Object key) 方法 ——> BaseLoadBalancer——>

public Server chooseServer(Object key) 方法 ——> IRule——> RoundRibbonRule轮询负载均衡方法

3.1.6 自定义负载均衡策略

  • 通过自定义配置类来实现(全局起作用):
package cn.itcast.order.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomIRuleConfig {

    /**
     * 自定义负载均衡策略
     * @return IRule
     */
    @Bean
    public IRule randomRule(){
        return new RandomRule();
    }
}
  • 通过 yml 文件来配置(指定微服务):
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice #注册这个module的服务名称

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10006/eureka

#该负载均衡规则只对名为 userservice 的微服务起作用
userservice:
  robbin:
    NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则

  • 这俩个全局的作用的负载均衡策略优先级高!!

3.1.7 饥饿加载

  • Ribbon 默认是懒加载,既第一次访问的时候才去创建 LoadBalancerClient,请求时间会很长。
  • 饥饿加载则会在项目启动时创建,降低第一次访问所需要的时间。
  • 开启饥饿加载的配置:
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice #注册这个module的服务名称

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10006/eureka

userservice:
  robbin:
    NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则
 
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ribbon:
  eager-load:
    enabled: true #开启饥饿加载
    clients:  #指定饥饿加载的服务名称
      - userservice
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3.1.8 总结

  • Ribbon 负载均衡规则:
    • 规则接口叫做 IRule
    • 默认实现是 ZoneAvoidanceRule ,根据 zone 选择服务列表然后轮询负载均衡。
  • 负载均衡自定义方式:
    • 代码方式:
      • 配置类,配置灵活,但修改时需要重新打包发布。
    • 配置文件方式:
      • 直观方便,无需重新打包,但是无法做全局配置。
    • 饥饿加载:
      • 通过配置文件开启饥饿加载。
      • 指定要饥饿加载的服务名称,是个数组。

3 Nacos 注册中心

3.1 Nacos windos 启动命令

startup.cmd -m standalone

3.2 Nacos 依赖

  • 一般将其引入到父工程中。
  • 引入 nacos 后得把 eureka 的依赖注释或删除,防止冲突。
<!-- nacos服务端管理依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

<!-- nacos客户端依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.3 nacos 简易使用

3.3.1 客户端引入依赖

<!-- nacos客户端依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.2.2 修改客户端 application.yml 文件中的 nacos 配置

server:
  port: 8080

# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice #注册这个module的服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos服务地址
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

#eureka:
#  client:
#    service-url:
#      defaultZone: http://127.0.0.1:10006/eureka

userservice:
  robbin:
    NFLoadBalancerRuleClassName: com.netflix.loadBalancer.RandomRule #负载均衡规则

ribbon:
  eager-load:
    enabled: true #开启饥饿加载
    clients:  #指定饥饿加载的服务名称
      - userservice

3.4 nacos 服务分级存储模型

3.4.1 概念

  • 一个服务包含多个实例。
  • 例如提供一个叫做 userservice 的服务,他的实例为 userservice:8080userservice:8081 等等。
  • 随着业务规模越来越大,以前服务小,所有服务可能放在一个机房,机房炸了,服务也就没了。
  • 为了解决这个问题,我们会将一个服务的多个实例,部署到多个机房

3.4.2 集群粗解释

  • 拿上面的例子来说,一个服务可能有八个实例,八个实例被两两分配在四个机房,那么此时装有两个服务实例的一个机房就叫做集群。

3.4.3 nacos 服务分级存储模型定义

  • 三级:服务 ——> 集群 ——> 实例

3.4.5 服务跨集群调用问题

  • 由于跨集群调用,可能涉及两个不同集群之间距离很远,调用的话延迟很高。
  • 所以我们一般情况都是先本地调用,如果本地调用无法调用才去进行远程集群调用。

3.5 如何配置一个服务的集群属性

3.5.1 修改 application.yml 文件中的配置

  • 如果我们有多个实例,我们可以先将 cluster-name 设置为其中一个集群名称,然后启动其中几个实例。
  • 然后我们再修改 cluster-name 为别的集群名称。
server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: userservice #注册这个module的服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos服务地址
      discovery:
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      	cluster-name: SH #设置集群所在地区名称 SH 代指上海 HZ 代指杭州
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        cluster-name: HZ #设置集群所在地区名称 SH 代指上海 HZ 代指杭州
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

#eureka:
#  client:
#    service-url:
#      defaultZone: http://127.0.0.1:10006/eureka

3.5.2 nacos控制台结果

结果
在这里插入图片描述

3.5.3 nacos 根据服务分级存储模型的负载均衡策略

  • 我们可以在两个集群:
    • SH集群:orderservice、userservice1、userservice2、
    • HZ集群:userservice3
  • 我们在用 orderserviceuserservice 发起几次不同的请求。
  • 我们会发现,在 orderservice 同一集群的服务没有挂掉的时候,它也去请求了远程 HZ集群的 userservice3
  • 所以我们要解决这个问题,我们使用 nacos 根据服务分级存储模型的负载均衡策略。
  • orderserviceapplication.yml 文件中完成如下配置:
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice #注册这个module的服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos服务地址
      discovery:
        cluster-name: HZ

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true

logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

userservice: # 要做配置的微服务名称
  robbin:
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ribbon:
  eager-load:
    enabled: true #开启饥饿加载
    clients:  #指定饥饿加载的服务名称
      - userservice

3.5.4 nacos 权重负载均衡

  • 实际部署中每台机器的性能都不一样,我们希望性能好的机器多承担一些请求,性能差的少承担一点。
  • 为了解决这个问题,nacos 帮我提供了权重设置,权重越高,访问率就越高。
  • 我们可以直接在 nacos 的网页控制端直接修改不同的权重。
  • 这个带给我们的好处,我们可以用在服务升级的过程中。

3.5.5 nacos 环境隔离

  • nacos 中服务存储和数据存储这俩者的最外层都是一个叫做 命名空间(namespace) 的东西用来做最外层隔离。
  • 包含关系:
    • namespace > group > service/data
  • 我们可以在 nacos 控制台新建新的命名空间,然后到代码层面去实现分配。
# ...

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: mysql123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: orderservice #注册这个module的服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 #nacos服务地址
      discovery:
        cluster-name: HZ
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
        namespace: 55f76e06-f468-4723-a8f7-29a7f2004cbf # dev 命名空间的id
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

# ...

3.5.6 nacos 临时实例和非临时实例

  • 我们可以在 orderserviceapplication.yml 文件中完成如下配置:
# ...

spring:
 datasource:
 url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
 username: root
 password: mysql123456
 driver-class-name: com.mysql.cj.jdbc.Driver
application:
 name: orderservice #注册这个module的服务名称
cloud:
 nacos:
  server-addr: localhost:8848 #nacos服务地址
  discovery:
   cluster-name: HZ 
   namespace: 55f76e06-f468-4723-a8f7-29a7f2004cbf # dev 命名空间的id
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   ephemeral: false # 设置为非临时实例
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# ...

  • 如果是非实例状态,服务即使停了也不会被剔除,你可以再次启动。

3.5.7 nacos 和 eureka 的区别

  • nacos 支持服务端主动检测服务提供者状态。
    • 临时实例
      • 临时实例采用心跳模式。
      • 心跳不正常会被剔除服务列表。
    • 非临时实例
      • 非临时实例采用主动检测模式。
      • 心跳不正常不会被剔除服务列表。
      • 会对服务器造成比较大的压力。
  • nacos 支持服务列表更新就主动推送给消费者的消息推送模式,服务列表可以及时更新。
  • nacos 集群默认采用 AP 方式,当集群中存在非临时实例时,采用 CP 模式,而 eureka 采用 AP 模式。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 20:37:43  更:2021-09-12 20:37:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:49:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码