• SpringCloud Alibaba技术栈(二)Nacos服务治理


    源码-笔记:Code for Github

    第二章 Nacos服务治理

    1. 模块设计与实现

    ①首先创建maven项目,此项目作为父工程。把src文件夹删掉,修改pom文件,添加依赖版本控制,控制子模块依赖的版本。
    ②实体类模块创建(在微服务中,实体类单独作为一个模块,供其他微服务一起使用,不在每个单独的微服务中设置domain):添加子模块,右击项目,new module,创建maven项目,创建domain包,在包下创建数据库中表对应的各种实体,以及封装controller return数据的实体 CommonResult

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class CommonResult<T> {
        private int code;
        private String message;
        private T data;
        public CommonResult(Integer code,String message){
            this(code,message,null);
        }
    }
    

    在 controller 中使用实例:

    @RequestMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable Integer id){
        try {
    //            Payment payment = paymentService.getPaymentById(id);
            Payment payment = paymentServiceImpl1.getPaymentById(id);
            if (payment != null) {
                return new CommonResult<>(200, "查询成功", payment);
            } else {
                return new CommonResult<>(444, "没有对应记录,查询ID:" + id, null);
            }
        }
        catch (Exception e){
            return new CommonResult<>(444, "异常,没有对应记录,查询ID:" + id, null);
        }
    }
    

    ③添加子模块,右击项目,new module,创建maven项目,剩下操作与创建springboot项目一样:
    a.引入依赖,配置application.yml

    b.创建启动类:@SpringBootApplication,main方法中SpringApplication.run()

    c.开发dao,service,controller

    2. 服务注册到Nacos

    ①首先安装部署nacos,安装地址:Nacos安装地址

    双击运行bin目录下的startup.cmd即可

    这里的正确做法是:

    • 启动服务器:bin 目录进入CMD -> 执行 startup.cmd -m standalone

      启动命令(standalone代表着单机模式运行,非集群模式)

    • 关闭服务器:shutdown.cmd 或者 双击shutdown.cmd运行文件

    nacos的控制台界面地址:http://localhost:8848/nacos,默认用户名密码都是nacos

    ②注册微服务

    在微服务模块的pom文件下增加依赖:

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

    在启动类上添加注解:@EnableDiscoveryClient

    在配置文件下增加nacos地址:

    spring:
    	cloud:
    		nacos:
    			discovery:
    				server-addr: 127.0.0.1:8848
    

    先运行nacos再运行微服务,可以在nacos的服务列表上看到该微服务已经注册进来。

    3. 服务调用(使用restTemplate)

    使用restTemplate传递http请求,实现微服务间的调用。

    a.创建配置包,在包里创建配置类

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

    b.在controller中使用@Autowired注入,并调用其方法getForObject访问相关微服务的接口。

    c.DiscoveryClient的getInstances方法可以找到在nacos上注册的微服务接口的实例,通过instance的getHost方法getPort方法,可以找到接口访问地址。搭配b实现服务调用。

    实例代码:

    List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
    int index = new Random().nextInt(instances.size());
    ServiceInstance serviceInstance = instances.get(index);
    Product p = restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+pid,Product.class);
    

    4. 服务调用的负载均衡

    多个相同的服务共同承担消费者的调用。

    服务端负载均衡:请求从服务请求者发出,到达服务端时,由服务端决定调用哪个。

    客户端负载均衡:服务请求者在发出请求前就已经决定好调用哪个。

    在微服务中的controller上写代码,决定如何调用其他微服务,属于客户端负载均衡。

    4.1 自定义实现负载均衡

    int index = new Random().nextInt(instances.size());
    

    4.2 基于Ribbon实现负载均衡

    ①在RestTemplate 的生成方法上添加@LoadBalanced注解
    ②restTemplate调用时直接用服务名替换接口地址。如下:

    Product p = restTemplate.getForObject("http://service-product/product/"+pid,Product.class);
    

    可以在配置文件中添加相关配置,来修改Ribbon的策略。

    service-product: # 调用的提供者的名称
    	ribbon:
    		NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    

    5. 使用feign实现服务调用

    ①引入feign依赖

    <!--fegin组件-->
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    ②在主类上添加Fegin的注解:@EnableFeignClients//开启Fegin

    ③创建一个service, 并使用Fegin实现微服务调用,实例代码:

    @FeignClient("service-product")//声明调用的提供者的name
    public interface ProductService {
        //指定调用提供者的哪个方法
        //@FeignClient+@GetMapping 就是一个完整的请求路径 http://serviceproduct/product/{pid}
        @GetMapping(value = "/product/{pid}")
        Product findByPid(@PathVariable("pid") Integer pid);
    }
    

    调用:先注入,然后productService.findByPid(pid);

  • 相关阅读:
    SpringBoot jar包不支持jsp
    Spring Boot 启动报错:LoggingFailureAnalysisReporter
    spring boot与spring mvc的区别是什么?
    解决配置JAVA_HOME JDK版本不变的问题
    Linux下修改Mysql的用户(root)的密码
    CentOS/Linux 解决 SSH 连接慢
    Linux查看进程的所有子进程和线程
    Linux命令之pstree
    使用awk批量杀进程的命令
    lucene 自定义评分
  • 原文地址:https://www.cnblogs.com/RioTian/p/15978244.html
Copyright © 2020-2023  润新知