02SCA-Nacos注册中心简述

在不同的服务之间进行通信,需要服务的注册中心,便于服务之间的通信,中介者模式
Nacos是一个应用于服务注册与发现、配置管理的平台。基于SpringBoot写的程序
官网地址: https://nacos.io/zh-cn/docs/quick-start.html
市面上常用注册中心:
Zookeeper(搭建集群设计雅虎Apache),  Eureka(Netfix不更新),  Consul(Google)
Nacos(Alibaba开源双十一  活跃度,稳定可靠,简单易用,功能,性能,学习成本)

nacos的安装启动

下载与安装

前提条件:确保你电脑已配置JAVA_HOME环境变量(Nacos启动时需要),MySQL版本为5.7以上(MariaDB10.5以上)
下载地址:https://github.com/alibaba/nacos/releases

下载解压

02SCA-Nacos注册中心简述_第1张图片

导入Nacos需要的配置数据

解压文件中的conf目录的sql脚本没有创建数据库和字符编码的语句需要添加
02SCA-Nacos注册中心简述_第2张图片

DROP DATABASE IF EXISTS `nacos_config`;

CREATE DATABASE  `nacos_config` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

USE `nacos_config`;

再在小黑窗口执行Sql文件即可;

source d:/nacos-mysql.sql 

常见异常
在这里插入图片描述

Nacos中配置连接数据库

打开/nacos/conf/application.properties里打开默认配置,配置要连接的数据库

### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=root

启动与访问

默认条件下是集群方式启动,开发阶段没有必要集群启动,浪费内存
02SCA-Nacos注册中心简述_第3张图片

在解压文件的目录中打开小黑窗口,输入如下命令: 
当然也可以使用Idea启动nacosidea启动sentinel,mysql,nacos常用配置_闪耀太阳de超级piracy的博客-CSDN博客

startup.cmd -m standalone

打开浏览器,输入http://localhost:8848/nacos
用户名:nacos  密码:nacos
在这里插入图片描述

 常见异常
出现如下异常时,说明连接数据库出现异常,请检查数据库是否启动,conf配置连接数据库是否正确

 服务注册

discovery该依赖会对web依赖服务进行监听,当监听到服务启动的时,discovery依赖就会对web依赖发起请求,进行服务的注册;  discovery依赖每隔5s通过任务调度ScheduledExecutorService向nacos服务发送BeatInfo进行服务监听,15s监听不到BeatInfo包健康实例数就会显示为0,30s监听不到BeatInfo包服务就会消失

创建服务提供者工程sca-provider继承parent工程(01-sca),其pom.xml文件内容如下: 



    
        01-sca
        com.jt
        1.0-SNAPSHOT
    
    4.0.0
    sca-provider
    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
    

创建并修改配置文件application.yml(或者application.properties),实现服务注册:
注意:服务名不要使用下划线(“_”),应使用横杠(“-”),这是规则。

server:
   port: 8081
spring:
  application:
    name: sca-provider #进行服务注册必须配置服务名
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

创建启动类并启动
前提条件是mysql,nacos都需要启动

@SpringBootApplication
public class ProviderApplication {

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

02SCA-Nacos注册中心简述_第4张图片

 服务之间的调用

在sca-provider项目中创建服务提供方对象,基于此对象对外提供服务

@RestController
public class ProviderController {
    /**
     * 基于@Value注解告诉springboot,读取配置文件(bootstrap.yml)中
     * 的server.port的值,假如读取不到则给一个默认值8080.
     */
    @Value("${server.port:8080}")
    private String server;

    @GetMapping("/provider/echo/{msg}")
    public String doRestEcho1(@PathVariable("msg") String msg){
        //return server+" say hello "+msg;
        //假如不想执行字符串的拼接,可以采用如下方式
        return String.format("%s say hello %s",server,msg);
        //如上语句中的s%为一个字符串占位符,server,msg的值最后会替换s%
    }
}

创建服务消费者工程(sca-consumer),继承parent工程(01-sca),其pom.xml文件内容如下



    
        01-sca
        com.jt
        1.0-SNAPSHOT
    
    4.0.0
    sca-consumer
    
   
    
    
        org.springframework.boot
        spring-boot-starter-web
    
    
    
        com.alibaba.cloud
        spring-cloud-starter-alibaba-nacos-discovery
    
    

创建sca-consumer服务中的配置文件application.yml

server:
  port: 8090
spring:
  application:
    name: sca-consumer #服务注册时,服务名必须配置
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #从哪里去查找服务

服务发现及RestTemplate调用(企业很少用)

创建消费端启动类并实现服务消费
且添加如下方法,用于创建RestTemplate对象.(模板方法模式)

@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
    /**
     * 创建RestTemplate对象,可以基于此对象进行远端服务调用,
     * 此对象封装了远程服务调用的协议和相关方法.
     */
    @Bean
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }
}

定义sca-consumer服务的消费端Controller,在此对象方法内部实现远端服务调用

@RestController
public class ConsumerController {
    //IOC-(资源整合-坐享其成)->Spring框架的目标(资源整合)
    //DI-依赖注入(属性注入,构造注入,set注入):注入之前要查找(依赖查找-DL)
    @Autowired //属性注入 (但是属性不能使用final修饰)
    private  RestTemplate restTemplate;
    //@Autowired //推荐构造注入 (假如只有一个构造方法autowired也可以省略)
    //public ConsumerController(RestTemplate restTemplate){
    //    this.restTemplate=restTemplate;
    //}

    @Value("${server.port:8080}")
    private String serverPort;
    
    @GetMapping("/consumer/doRestEcho1")
    public String doRestEcho01(){
        
        String url="http://localhost:8081/provider/echo/{msg}";
        //基于RestTemplate借助http协议向远端服务发起Get请求
        //getForObject远端请求类型
        //url远端资源Url
        //String.class远端服务返回值类型
        //serverPort调用远端服务需要传递的参数
        return restTemplate.getForObject(url,
                String.class,serverPort);
    }
}

LoadBalancerClien负载均衡

ConsumerController类,注入LoadBalancerClient接口,其实现类是RibbonLoadBalancerClient对象,负载均衡实现默认是Nacos集成了Ribbon来实现的,并添加doRestEcho2方法,然后进行服务访问.

@RestController
public class ConsumerController {
   
    @Autowired
    private LoadBalancerClient loadBalancerClient;
   
    @GetMapping("/consumer/doRestEcho2")
    public String doRestEcho02(){

        //1)基于服务名(这个名字是nacos注册中心中的一个服务名)获取服务实例
        ServiceInstance serviceInstance =
        loadBalancerClient.choose("sca-provider");
        //2)基于服务实例构建远端服务url
        String url="http://%s:%s/provider/echo/{msg}";
        String ip=serviceInstance.getHost();
        int port=serviceInstance.getPort();
        url=String.format(url,ip,port);
        //3)进行远端服务调用
        return restTemplate.getForObject(url,
                             String.class,serverPort);
    }    
}

@LoadBalanced

当使用 @LoadBalanced注解描述RestTemplate对象时,RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,拦截到请求url后,会基于请求url中的服务名获取具体的服务实例,然后基于服务实例重新构建新的url,再基于新的url进行服务调用.

@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){
    return new RestTemplate();
}
    @Autowired
    private RestTemplate loadBalancedRestTemplate;

    @GetMapping("/consumer/doRestEcho3")
    public String doRestEcho03(){
        
        String url=String.format("http://%s/provider/echo/{msg}","sca-provider");
        return loadBalancedRestTemplate.getForObject(url,
                String.class,serverPort);
    }
}

服务发现及Feign调用 

Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现;Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,现有Spring cloud维护,更名为 OpenFeign。

添加openfeign依赖(负载均衡实现默认是Nacos集成了Ribbon来实现的)


    org.springframework.cloud
    spring-cloud-starter-openfeign

启动类上添加@EnableFeignClients注解
@EnableFeignClients 用于描述启动类或配置类,项目在启动时,就会启动一个FeignStarter组件,这个组件会对项目中使用了@FeignClient注解描述的接口进行代理对象的创建.

@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {…}

Consumer服务通过Service层进行服务调用
 @FeignClient 注解描述的接口为[远程服务]调用接口,
 此接口不需要写实现类,由底层创建接口实现类,属于JDK代理,直接生产字节码文件,对象会交给spring管理,此对象默认的bean名称默认使用name或value属性的值,推荐基于contextId手动指定一个Bean名字

@FeignClient(name="sca-provider",
             contextId = "remoteProviderService",
             fallbackFactory = ProviderFallbackFactory.class)
public interface RemoteProviderService {//明修栈道暗度陈仓
      //Rest风格:通过URI定义资源,通过请求动作操作资源
      @GetMapping("/provider/echo/{string}")
      String echoMessage(@PathVariable("string") String msg);
}

创建controller层进行服务调用

@RestController
@RequestMapping("/consumer/ ")
public class FeignConsumerController {
    @Autowired
    private RemoteProviderService remoteProviderService;
   
    @GetMapping("/echo/{msg}")
    public String doFeignEcho(@PathVariable  String msg){
        return remoteProviderService.echoMessage(msg);
    }
}

快速启动多个服务小技巧

02SCA-Nacos注册中心简述_第5张图片

 

调用服务异常处理

进行远程服务调用时,假如调用的服务突然不可用了或者调用过程超,需要进行异常的处理
创建异常处理类

@Slf4j
@Component
public class ProviderFallbackFactory implements FallbackFactory {
    //创建日志对象
    //private static final Logger log=
            //LoggerFactory.getLogger(ProviderFallbackFactory.class);
    @Override
    public RemoteProviderService create(Throwable throwable) {
/**        return new RemoteProviderService() {
            @Override
            public String echoMessage(String msg) {
                //...报警...(发短信,email,日志.....)
                return "服务暂时不可用,稍等片刻再访问";
            }
        };
*/  
          return msg -> {//lambda表达式 (JDK8中的语法)
                //...报警...(发短信,email,日志.....)
                log.error("error: {} ","sca-provider服务调用失败");
                return "服务暂时不可用,稍等片刻再访问";
          };
    }
}

配置文件application.yml中添加如下配置,启动feign方式调用时的服务中断处理机制

feign:  
  hystrix:
    enabled: true #默认值为false
logging:
  file:
    name: consumer.log  #将日志记录到文件

Consumer服务通过Service层进行服务调用

@FeignClient(name = "sca-provider", contextId = "remoteProviderService",
             fallbackFactory = ProviderFallbackFactory.class)
public interface RemoteProviderService {
    @GetMapping("/provider/echo/{msg}")
    public String echoMsg(@PathVariable String msg);
}

服务之间调用实现负载均衡 

负载均衡策略:
02SCA-Nacos注册中心简述_第6张图片

 方式一:在配置类/启动类中

    /** 假如默认负载均衡策略不能满足我们需求
     * 具体方案:构建IRule接口实现类对象,
     * 并将此对象交给spring管理即可.
     * 这里以随机负载均衡策略为例进行实践.*/
     
     @Bean
     public IRule rule(){
         return new RandomRule();
     }

 方式二:配置文件中,将来可以写到配置中心

#直接在配置文件中的配置,其优势是,可以将配置提取到配置中心
sca-provider: #基于服务名指定负载均衡策略
    ribbon:
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

你可能感兴趣的:(SCA,java)