92.【SpringCloud NetFilx】(六)

简介: 92.【SpringCloud NetFilx】
  1. 修改控制层对服务层的访问路径
  • 使用Ribbon负载均衡,我们这里不应该写死。而应该通过id名(服务提供者),进行获取 SpringCloud-provider-dept
//  设置服务层的前缀为常量
    //private static final String REST_URL_PREFIX="http://localhost:8081";
    // 使用Ribbon负载均衡,我们这里不应该写死。而应该通过id名(服务提供者),进行获取 SpringCloud-provider-dept
    private static final String REST_URL_PREFIX="http://SpringCloud-provider-dept";
package com.jsxs.controller;
import com.jsxs.pojo.Dept;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@RestController
public class DeptConsumerController {
    //注意: 这里我们只是引入了实体类的数据,并没有引入service接口
    //思考: 消费者界面不应该存在Dao层也不应该存在Service层,该如何使用服务呢
    //RestTemplate  ... 我们直接调用就行,但需要注入到Spring中
    @Resource
    // (URI url, 实体 map,Class<T> responseType) 地址---- 实体 ----返回类型.class
    private RestTemplate restTemplate;   // 提供多种便捷访问远程   访问http服务的方法,简单的Rest
    //  设置服务层的前缀为常量
    //private static final String REST_URL_PREFIX="http://localhost:8081";
    // 使用Ribbon负载均衡,我们这里不应该写死。而应该通过id名(服务提供者),进行获取 SpringCloud-provider-dept
    private static final String REST_URL_PREFIX="http://SpringCloud-provider-dept";
    //  根据id进行数据的查找
    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long deptno){
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/queryById/"+deptno,Dept.class);
    }
    //  添加数据
    @RequestMapping("/consumer/dept/add")
    public boolean add(Dept dept){
        return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
    }
    //  查找全部数据
    @RequestMapping("/consumer/dept/all")
    public List<Dept> all(){
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/all",List.class);
    }
}

结论: Eureka和Ribbon整合之后,客户端可以直接调用,不再用关心我们的IP地址和端口号。 为什么? ①因为我们实现了负载均衡,所以客户端像跳哪个服务器,负载均衡会帮助我们寻找。②我们在controller做了手脚,通过注册服务的id进行跳转。

3.使用Ribbon实现负载均衡

流程图:

(Ribbon有两个步骤:1.去Eureka集群中查找可用的服务列表;2.通过负载均衡的算法,从服务提供者中选择一个看起来比较OK的)

1.新建两个服务提供者Moudle:springcloud-provider-dept-8003、springcloud-provider-dept-8002

CREATE DATABASE db03;
USE db03;
CREATE TABLE dept(
  deptno BIGINT(20) Not Null PRIMARY KEY AUTO_INCREMENT,
  dname VARCHAR(60) DEFAULT NULL,
  db_source VARCHAR(60) DEFAULT NULL
);
INSERT INTO dept(dname,db_source) VALUES('开发部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('人事部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('财务部',DATABASE());
INSERT INTO dept(dname,db_source) VALUES('售后部',DATABASE());

2.参照springcloud-provider-dept-8001 依次为另外两个Moudle添加pom.xml依赖 、resourece下的mybatis和application.yml配置,Java代码

3.启动所有服务测试(根据自身电脑配置决定启动服务的个数),访问http://eureka7001.com:7001/查看结果

4.进行用户访问

第一次刷新

第二次刷新

Eureka

内存

以上这种每次访问http://localhost/consumer/dept/list随机访问集群中某个服务提供者,这种情况叫做轮询,轮询算法在SpringCloud中可以自定义。

4.自定义负载均衡算法

如何切换或者自定义规则呢?

(1).切换系统已有均衡算法

默认的是轮询,如果我们需要切换。那么我们就自己配置一个类

@Bean
    public IRule myIRule(){
        return new RandomRule();
    }

1.在springcloud-provider-dept-80模块下的ConfigBean中进行配置,切换使用不同的规则

package com.jsxs.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration  //  相当于application.xml文件
public class ConfigBean {
    // IRule :
    /**
     *      1.AvailabilityFilteringRule  先过滤掉奔溃(跳匝)的服务,对剩下的服务进行轮询
     *      2.RoundRobinRule  轮询   《默认》
     *      3  .RoundRobinRule 随机
     *      4. RetryRule 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内运行。
     *
     */
    @LoadBalanced   //  配置负载均衡,只需要添加一个注解就可以
    @Bean       //  把RestTemplate注入到Spring中去
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    // 启用随机作为Ribbon的算法
    @Bean
    public IRule myIRule(){
        return new RandomRule();
    }
}

2.启动测试: 发现真的变成随机负载了。

(2).自定义负载均衡算法

1.切记我们自定义的负载均衡算法,不能被Spring扫描到。所以我们自定义的算法需要放在启动类的上一级

自定义的算法会覆盖默认的算法均衡
FooConfiguration必须是@Configuration,但请注意,它不在主应用程序上下文的@ComponentScan
中,否则将由所有@RibbonClients共享。如果您使用@ComponentScan(或@SpringBootApplication)
,则需要采取措施避免包含(例如将其放在一个单独的,不重叠的包中,或者指定要在@ComponentScan)。

2.自定义配置的java文件 murule/JsxsRandomRule.java

package com.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class JsxsRandomRule extends AbstractLoadBalancerRule {
    public JsxsRandomRule() {
    }
    @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;
            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
                List<Server> upList = lb.getReachableServers();   // 获得活着的服务
                List<Server> allList = lb.getAllServers();   // 获得全部的服务
                int serverCount = allList.size();      //
                if (serverCount == 0) {
                    return null;
                }
                int index = this.chooseRandomInt(serverCount);   //生成随机数
                server = (Server)upList.get(index);  //从活着的服务中,随机获取一个
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
                    server = null;
                    Thread.yield();
                }
            }
            return server;
        }
    }
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
}

3.在启动类上声明注解

package com.jsxs;
import com.myrule.JsxsRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@SpringBootApplication
@EnableEurekaClient
// 在微服务启动的时候,就会加载我们自定义的均衡算法。
@RibbonClient(name = "SpringCloud-provider-dept",configuration = JsxsRule.class)  // 服务端的ID名 自定义配置的类
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}
  1. 切换成我们自定义的负载均衡 myrule/JsxsRule.java
package com.myrule;
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 JsxsRule {
    // 启用随机作为Ribbon的算法
    @Bean
    public IRule myIRule(){
        return new JsxsRandomRule();
    }
}

5.测试无误。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
5月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
882 3
|
3月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
10月前
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
11月前
|
前端开发 Java Nacos
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
本文介绍了如何使用Spring Cloud Alibaba 2023.0.0.0技术栈构建微服务网关,以应对微服务架构中流量治理与安全管控的复杂性。通过一个包含鉴权服务、文件服务和主服务的项目,详细讲解了网关的整合与功能开发。首先,通过统一路由配置,将所有请求集中到网关进行管理;其次,实现了限流防刷功能,防止恶意刷接口;最后,添加了登录鉴权机制,确保用户身份验证。整个过程结合Nacos注册中心,确保服务注册与配置管理的高效性。通过这些实践,帮助开发者更好地理解和应用微服务网关。
1897 0
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
|
12月前
|
人工智能 安全 Java
AI 时代:从 Spring Cloud Alibaba 到 Spring AI Alibaba
本次分享由阿里云智能集团云原生微服务技术负责人李艳林主讲,主题为“AI时代:从Spring Cloud Alibaba到Spring AI Alibaba”。内容涵盖应用架构演进、AI agent框架发展趋势及Spring AI Alibaba的重磅发布。分享介绍了AI原生架构与传统架构的融合,强调了API优先、事件驱动和AI运维的重要性。同时,详细解析了Spring AI Alibaba的三层抽象设计,包括模型支持、工作流智能体编排及生产可用性构建能力,确保安全合规、高效部署与可观测性。最后,结合实际案例展示了如何利用私域数据优化AI应用,提升业务价值。
1134 4
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
764 5
|
Java Spring
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
313 1
|
负载均衡 Java API
【Spring Cloud生态】Spring Cloud Gateway基本配置
【Spring Cloud生态】Spring Cloud Gateway基本配置
1260 0
|
Java API 开发工具
Spring Boot与Spring Cloud Config的集成
Spring Boot与Spring Cloud Config的集成

热门文章

最新文章