springboot2原理实战(20)--微服务自己实现注册发现,负载均衡小demo

简介: springboot2原理实战(20)--微服务自己实现注册发现,负载均衡小demo

概要


之前了解了很多的springboot的基础知识,现在实战下,做个微服务,什么是微服务呢?


就是按业务拆分模块,然后模块间通过restful或者rpc调用。

本文主要写


①一个服务端,一个客户端,服务端写个接口,客户端通过restful查询。


②加个注册中心:服务端把注册地址到给zookeeper,客户端通过zookeeper查询数据


③多个服务注册到zookeeper,实现负载均衡。


服务端代码地址:


https://github.com/hufanglei/springboot-v-study/tree/a-mall-product


关键代码展示:


/**
 * 服务注册
 */
@Component
public class ServiceRegister implements ApplicationRunner {
    @Value("${zookeeper.address}")
    private String zkAddress;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        CuratorFramework client = CuratorFrameworkFactory.newClient(zkAddress, new RetryOneTime(1000));
        client.start();
        client.blockUntilConnected();
        ServiceInstance<Object> instance = ServiceInstance.builder().name("product").address("192.168.157.1").port(8080).build();
        ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder
                                                    .builder(Object.class)
                                                    .client(client)
                                                    .basePath("/soa").build();
        serviceDiscovery.registerService(instance);
        serviceDiscovery.start();
        System.out.println("service register ok");
    }
}


客户端代码地址:


https://github.com/hufanglei/springboot-v-study/tree/a-mall-product-web


关键代码展示:


最简单的resful版调用


public class Client {
    public static String BASE_URL ="http://127.0.0.1:8080";
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        Response object = restTemplate.getForObject(BASE_URL + "/soa/product/1", Response.class);
        System.out.println(new Gson().toJson(object));
        String data = restTemplate.getForObject(BASE_URL + "/soa/product/1", String.class);
        System.out.println(data);
        System.out.println(new Gson().toJson(new Gson().fromJson(data, Response.class)));
        System.out.println(new Gson().toJson(new Gson().fromJson(data, Map.class).get("data")));
    }
}


zookeeper版调用


public class AMallProductWebApplication {
  public static String ZKADDRESS ="192.168.157.111:2181";
  public static void main(String[] args) throws Exception {
  CuratorFramework client = CuratorFrameworkFactory.newClient(ZKADDRESS, new RetryOneTime(1000));
  client.start();
  client.blockUntilConnected();
  ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder
    .builder(Object.class)
    .client(client)
    .basePath("/soa").build();
  Collection<ServiceInstance<Object>> list = serviceDiscovery.queryForInstances("product");
  list.forEach((instance) ->{
    System.out.println(instance.getAddress());
    System.out.println(instance.getPort());
    RestTemplate restTemplate = new RestTemplate();
    Response resp = restTemplate.getForObject("http://"+instance.getAddress() +":"+instance.getPort() + "/soa/product/1", Response.class);
    System.out.println(resp.getCode());
    System.out.println(resp.getMsg());
    System.out.println(resp.getData());
  });
  }
}


负载均衡+zookeeper版调用

/**
 * 轮询器
 */
public class LoaderBalance {
    private int index = 0;
    private List<String> services;
    public LoaderBalance(List<String> services) {
        this.services = services;
    }
    public String choose(){
        String service = services.get(index);
        index++;
        if(index >= services.size()){
            index = 0;
        }
        return service;
    }
}


public class AppBanlance {
  public static String ZKADDRESS ="192.168.157.111:2181";
  public static void main(String[] args) throws Exception {
  CuratorFramework client = CuratorFrameworkFactory.newClient(ZKADDRESS, new RetryOneTime(1000));
  client.start();
  client.blockUntilConnected();
  ServiceDiscovery<Object> serviceDiscovery = ServiceDiscoveryBuilder
    .builder(Object.class)
    .client(client)
    .basePath("/soa").build();
  Collection<ServiceInstance<Object>> list = serviceDiscovery.queryForInstances("product");
  final List<String> services = new ArrayList<>();
  list.forEach((instance) ->{
    services.add(instance.getAddress() + ":" + instance.getPort());
  });
  System.out.println(services);
  LoaderBalance lb = new LoaderBalance(services);
  for (int i=0;i<10;i++){
    RestTemplate restTemplate = new RestTemplate();
    Response resp = restTemplate.getForObject("http://"+lb.choose()+ "/soa/product/1", Response.class);
    System.out.println(resp.getCode());
    System.out.println(resp.getMsg());
    System.out.println(resp.getData());
  }
  }
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
监控 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注册中心服务 构建商品
1571 3
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
3056 0
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1500 0
|
11月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1508 2
Spring Boot 3.x 微服务架构实战指南
|
12月前
|
消息中间件 Ubuntu Java
SpringBoot整合MQTT实战:基于EMQX实现双向设备通信
本教程指导在Ubuntu上部署EMQX 5.9.0并集成Spring Boot实现MQTT双向通信,涵盖服务器搭建、客户端配置及生产实践,助您快速构建企业级物联网消息系统。
3211 1
|
11月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
693 4
|
11月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
838 2
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
1238 4