springcloud+dubbo+nacos搭建(nacos使用mysql存储)

前面两篇讲了不用springcloud做粘合,直接springboot+dubbo+nacos+sentinel的搭建

这篇讲用springcloud做粘合是怎么搞的

一、nacos作为注册中心

1.原理

 

2.调用方business服务代码

场景是business项目调用storage项目

目录

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第1张图片

pom.xml



    
        test-spring-cloud-alibaba
        com.sid
        1.0-SNAPSHOT
    
    4.0.0

    business

    
        8
        8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
            2.1.1.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-dubbo
            2.1.1.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            2.1.1.RELEASE
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            1.3.2
        
        
            mysql
            mysql-connector-java
            5.1.46
            runtime
        

        
        
            com.sid
            api
            1.0-SNAPSHOT
        

        
        
            org.apache.httpcomponents
            httpclient
            4.5.6
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.0.1.RELEASE
            
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.7
                
                    ${basedir}/src/main/resources/generator/generatorConfig.xml
                    true
                    true
                
                
                    
                    
                        mysql
                        mysql-connector-java
                        5.1.46
                        runtime
                    
                
            
        
    

bootstrap.yml

spring:
  application:
    name: app-business
  cloud:
    nacos:
      # Nacos 服务发现与注册配置
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848

 application.yml

server:
  port: 8085


###起个名字作为服务名称(该服务注册到nacos注册中心的名称,比如订单服务)
spring:
  application:
    name: app-business
  datasource:
    url: jdbc:mysql://localhost:3306/test-business
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

# Dubbo Application
dubbo:
  # Dubbo Protocol
  protocol:
    name: dubbo
    ## Random port
    port: -1
  ## Dubbo Registry
  registry:
    address: spring-cloud://localhost
  application:
    name: app-business
  scan:
    #这里是表明RPC接口包的package
    base-packages: com.sid.rpc.service
  cloud:
    #business这个服务需要调用order和storage服务,这个配置表示去订阅他们
    subscribed-services: app-order,app-storage
## 该配置节点为独立的节点,不是在在spring的节点下
mybatis:
  mapper-locations: classpath:mapping/*.xml  #注意:一定要对应mapper映射xml文件的所在路径
  type-aliases-package: com.sid.model  # 注意:对应实体类的路径
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台打印sql

# log config
logging:
  config: classpath:logback-spring.xml

启动类

package com.sid;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
@EnableDubbo
@MapperScan("com.sid.mapper")
public class BusinessApp {
    public static void main(String[] args) {
        SpringApplication.run(BusinessApp.class, args);
    }

}

 BusinessServiceImpl.java

该类里面就是用dubbo去RPC调用storage服务和order服务

package com.sid.service;

import com.sid.mapper.BusinessMapper;
import com.sid.model.Business;
import com.sid.rpc.service.model.Order;
import com.sid.rpc.service.service.OrderServiceApi;
import com.sid.rpc.service.service.StorageServiceApi;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class BusinessServiceImpl implements BusinessService{

    @Reference(check = false,group = "order-provider", version = "1.0.0")
    OrderServiceApi orderServiceApi;

    @Reference(check = false,group = "storage-provider", version = "1.0.0")
    StorageServiceApi storageServiceApi;

    @Resource
    BusinessMapper businessMapper;

    /**
     * 采购
     */
    @Transactional
    @Override
    public void purchase(String userId, String commodityCode, int orderCount) {

        Business b = new Business();
        b.setUserId(userId);
        b.setCommodityCode(commodityCode);
        b.setOrderCount(orderCount);

        int i = businessMapper.insertSelective(b);

        String storageDeductResult = storageServiceApi.deduct(commodityCode, orderCount);
        System.out.println(storageDeductResult);

        Order order = orderServiceApi.create(userId, commodityCode, orderCount);

        String orderCreateResult = order.getMsg();


        if(!storageDeductResult.equals("success") || !orderCreateResult.equals("success")){
            System.out.println("resutl storage service :"+storageDeductResult);

            System.out.println("resutl order service :"+orderCreateResult);

            throw new RuntimeException("BusinessServiceImpl purchase fail");
        }

    }

}

2.被调用方storage服务代码

目录

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第2张图片

pom.xml



    
        test-spring-cloud-alibaba
        com.sid
        1.0-SNAPSHOT
    
    4.0.0

    storage

    
        8
        8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
            2.1.1.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-dubbo
            2.1.1.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            2.1.1.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            2.1.1.RELEASE
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            1.3.2
        
        
            mysql
            mysql-connector-java
            5.1.46
            runtime
        

        
            com.sid
            api
            1.0-SNAPSHOT
        

        
            org.apache.httpcomponents
            httpclient
            4.5.6
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.0.1.RELEASE
            
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.7
                
                    ${basedir}/src/main/resources/generator/generatorConfig.xml
                    true
                    true
                
                
                    
                    
                        mysql
                        mysql-connector-java
                        5.1.46
                        runtime
                    
                
            
        
    

bootstrap.yml

spring:
  application:
    name: app-storage
  cloud:
    nacos:
      # Nacos 服务发现与注册配置
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848

application.yml

server:
  port: 8083

###起个名字作为服务名称(该服务注册到nacos注册中心的名称,比如订单服务)
spring:
  application:
    name: app-storage
  datasource:
    url: jdbc:mysql://localhost:3306/test-storage
    username: root
    password: root
    # 使用druid数据源
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      # Nacos 服务发现与注册配置
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848

# Dubbo Application
dubbo:
  # Dubbo Protocol
  protocol:
    name: dubbo
    ## Random port
    port: -1
  ## Dubbo Registry
  registry:
    # 挂载到 Spring Cloud 注册中心
    address: spring-cloud://localhost
  application:
    name: app-storage
  scan:
    base-packages: com.sid.rpc.service

## 该配置节点为独立的节点,不是在在spring的节点下
mybatis:
  mapper-locations: classpath:mapping/*.xml  #注意:一定要对应mapper映射xml文件的所在路径
  type-aliases-package: com.sid.model  # 注意:对应实体类的路径
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台打印sql

启动类

package com.sid;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.sid.mapper")
@EnableDubbo
public class StorageApp {
    public static void main(String[] args) {
        SpringApplication.run(StorageApp.class, args);
    }
}

rpc实现类

package com.sid.rpc.service;


import com.sid.rpc.service.service.StorageServiceApi;
import com.sid.service.StorageService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service(group = "storage-provider", version = "1.0.0")
public class StorageServiceRpcImpl implements StorageServiceApi {

    @Autowired
    private com.sid.service.StorageService StorageService;

    /**
     * 商品扣库存
     * */
    @Override
    public String deduct(String commodityCode, int count) {

        return StorageService.deduct(commodityCode,count);
    }
}

业务service实现类

package com.sid.service;

import com.sid.mapper.StorageMapper;
import com.sid.model.Storage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class StorageServiceImpl implements StorageService {

    @Resource
    private StorageMapper storageMapper;

    /**
     * 商品扣库存
     * */
    @Override
    @Transactional
    public String deduct(String commodityCode, int count) {
        Storage storage = storageMapper.selectByPrimaryKey(commodityCode);
        Integer storageCount = storage.getStorageCount();
        storage.setStorageCount(storageCount - count);
        int i = storageMapper.updateByPrimaryKey(storage);
        //int ii = 1/0;
        if(i == 1){
            return "success";
        }
        return "fail";
    }
}

3 RPC接口包服务代码

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第3张图片

StorageServiceApi.java

package com.sid.rpc.service.service;

public interface StorageServiceApi {

    String deduct(String commodityCode, int count);
}

4 启动nacos,启动后这两个服务

http://localhost:8848/

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第4张图片二、nacos作为配置中心

1.原理 

1.Nacos Config 数据结构

Nacos Config 主要通过 dataId 和 group 来唯一确定一条配置.

Nacos Client 从 Nacos Server 端获取数据时,调用的是此接口 ConfigService.getConfig(String dataId, String group, long timeoutMs)。

2.Spring Cloud 应用获取数据

dataId

在 Nacos Config Starter 中,dataId 的拼接格式如下

${prefix} - ${spring.profiles.active} . ${file-extension}

prefix 默认为 spring.application.name 的值,也可以通过springboot的application.yml中的配置项 spring.cloud.nacos.config.prefix来配置。

spring.profiles.active 即为当前环境对应的 profile

注意,当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成

${prefix}.{file-extension}

file-extension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension来配置。 默认是 properties 类型。

group

group 默认为 DEFAULT_GROUP,可以通过 spring.cloud.nacos.config.group 配置。

默认情况下,会加载命名空间=public,DataID=${spring.application.name}.properties,Group=DEFAULT_GROUP的配置。

3.自动注入

Nacos Config Starter 实现了 org.springframework.cloud.bootstrap.config.PropertySourceLocator接口,并将优先级设置成了最高。

在 Spring Cloud 应用启动阶段,会主动从 Nacos Server 端获取对应的数据,并将获取到的数据转换成 PropertySource 且注入到 Environment 的 PropertySources 属性中,

所以使用 @Value 注解也能直接获取 Nacos Server 端配置的内容。

2.读nacos命名空间public里面的配置

默认情况下,会加载命名空间=public,DataID=${spring.application.name}.properties,Group=DEFAULT_GROUP的配置。

作为配置中心举例就只以business项目举例了

business项目在前面的代码基础上,加入下面的改动

pom.xml加入

        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            2.1.1.RELEASE
        

bootstrap.yml加入

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第5张图片

获取配置中心的配置

这里可以看到,直接用spring的@Value就能读到nacos配置中心的配置了(前提是用springcloud来粘合的)

Nacos Config Starter 实现了 org.springframework.cloud.bootstrap.config.PropertySourceLocator接口,并将优先级设置成了最高。

在Spring Cloud应用启动阶段,会主动从Nacos Server端获取对应的数据,并将获取到的数据转换成PropertySource且注入到Environment的PropertySources属性中,所以使用@Value注解也能直接获取Nacos Server端配置的内容。

package com.sid.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class NacosConfig {

    @Value("${business.testConfig}")
    private String businessTestConfig;

    @Value("${ip}")
    private String ip;
    
    public String getBusinessTestConfig() {
        return businessTestConfig;
    }

    public void setBusinessTestConfig(String businessTestConfig) {
        this.businessTestConfig = businessTestConfig;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

}

 这样子搞,是读的nacos的命名空间public里面的东西

默认情况下,会加载命名空间=public,DataID=${spring.application.name}.properties,Group=DEFAULT_GROUP的配置。

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第6张图片

在配置列表public命名空间里面创建1个文件,文件的名字是app-business,这个文件的名字要跟该应用的名字一样,文件格式是properties

app-business内容是

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第7张图片

启动的时候从日志就能看到本应用读的是nacos配置中的哪个文件,文件里面有些什么内容

写个controller来请求验证一下读到的配置文件的内容

package com.sid.controller;

//import com.sid.config.NacosConfig;

import com.sid.config.NacosConfig;
import com.sid.model.Business;
import com.sid.service.BusinessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class BusinessController {

    @Autowired
    BusinessService businessService;

    @Autowired
    NacosConfig nacosConfig;

    /**
     * 采购
     */
    @RequestMapping(value = "business/purchase",method = RequestMethod.POST)
    public void purchase(String userId, String commodityCode, int orderCount) {
        businessService.purchase(userId,commodityCode,orderCount);
    }

    @RequestMapping(value = "business/config",method = RequestMethod.GET)
    public NacosConfig config() {
        return nacosConfig;
    }
}

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第8张图片

3.nacos配置中心以命名空间区分开发、测试环境不同的配置

在nacos的界面创建2个命名空间,一个是dev,

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第9张图片

在配置列表中,dev命名空间下,创建配置文件app-business 

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第10张图片

内容如下

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第11张图片

代码

主要是修改bootstrap.yml的配置

加上namespace,注意这里的命名空间不是用名字,不是用dev,而是用它的ID,命名空间的ID

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第12张图片

启动日志其实就能看到读到了dev命名空间里面的app-business配置文件中的东西了

4.多个服务共用一个公共的配置文件

在nacos的管理界面加入配置文件application.properties,注意要把后缀.properties写全

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第13张图片

内容

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第14张图片

主要是修改bootstrap.yml的配置,加一个配置,注意要把后缀.properties写全

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第15张图片

启动日志

可以看到去加载了文件application.properties

2021-05-27 16:55:40.361  WARN --- [main] c.a.c.n.c.NacosPropertySourceBuilder     Ignore the empty nacos configuration and get it based on dataId[application.properties] & group[DEFAULT_GROUP]
2021-05-27 16:55:40.369  INFO --- [main] c.a.c.n.c.NacosPropertySourceBuilder     Loading nacos data, dataId: 'app-business', group: 'DEFAULT_GROUP', data: business.testConfig=dev
ip=12345678
2021-05-27 16:55:40.373  WARN --- [main] c.a.c.n.c.NacosPropertySourceBuilder     Ignore the empty nacos configuration and get it based on dataId[app-business.properties] & group[DEFAULT_GROUP]
2021-05-27 16:55:40.373  INFO --- [main] b.c.PropertySourceBootstrapConfiguration Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='app-business.properties'}, NacosPropertySource {name='app-business'}, NacosPropertySource {name='application.properties'}]}

5.动态刷新配置

Nacos Config Starter 默认为所有获取数据成功的 Nacos 的配置项添加了监听功能,在监听到服务端配置发生变化时会实时触发 org.springframework.cloud.context.refresh.ContextRefresher 的 refresh 方法 。

如果需要对 Bean 进行动态刷新,给类添加 @RefreshScope 或 @ConfigurationProperties注解。

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第16张图片

6.Endpoint 信息查看(结合spring-boot-starter-actuator)

Springboot支持这一点,Nacos Config也同时可以使用Endpoint来暴露信息。

在maven 中添加 spring-boot-starter-actuator依赖,并在配置中允许 Endpoints 的访问。

        
            org.springframework.boot
            spring-boot-starter-actuator
            2.1.1.RELEASE
        

Spring Boot 1.x 中添加配置 management.security.enabled=false

Spring Boot 2.x 中添加配置 management.endpoints.web.exposure.include=*

management:
  endpoints:
    web:
      exposure:
        include: '*'

Spring Boot 1.x 可以通过访问 http://127.0.0.1:8085/nacos_config 来查看 Nacos Endpoint 的信息。

Spring Boot 2.x 可以通过访问 http://localhost:8085/actuator/nacos-config 来访问。

在idea中能看到一共有哪些mapping

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第17张图片

服务发现的

http://127.0.0.1:8085/actuator/nacos-discovery

三、nacosAPI及客户端的配置相关配置

配置 

nacos作为配置中心,客户端的配置见源码中的NacosConfigProperties类

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第18张图片

nacos作为注册中心,客户端的配置见源码中的NacosDiscoveryProperties类

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第19张图片

openApi

https://nacos.io/zh-cn/docs/open-api.html

比如查询服务列表

http://localhost:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=100

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第20张图片

获取配置

http://localhost:8848/nacos/v1/cs/configs?dataId=app-business&group=DEFAULT_GROUP

发布配置

 

curl -X POST 'http://127.0.0.1:8848/nacos/v1/cs/configs' -d 'dataId=nacos.example&group=com.alibaba.nacos&content=contentTest'  

四、nacos用mysql作为存储

1.初始化数据库

Nacos的数据库脚本文件在我们下载Nacos-server时的压缩包中就有。

进入nacos-server-1.4.1\nacos\conf目录,里面有个初始化文件:nacos-mysql.sql。

自己在mysql中创建一个nacos 的数据库,然后执行nacos-mysql.sql初始化脚本,成功后会生成一些表。

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第21张图片

2.修改配置文件

这里是需要修改Nacos-server的配置文件

Nacos-server其实就是一个Java工程或者说是一个Springboot项目,他的配置文件在nacos-server-1.4.1\nacos\conf目录下,名为 application.properties

把配置文件中关于mysql配置的部分打开,本来是注释了的,填入自己的mysql的IP账号密码:

#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql

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

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

### Connection pool configuration: hikariCP
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2

3.启动Nacos

先启动Nacos-server,在目录nacos-server-1.4.1\nacos\bin

cmd startup.cmd -m standalone

启动成功后进入Nacos控制台,此时的Nacos控制台中焕然一新,之前的数据都不见了

因为加入了新的数据源,Nacos从mysql中读取所有的配置文件,而我们刚刚初始化的数据库是干干净净的,自然不会有什么数据和信息显示。

4.验证是否持久化到数据库中

添加一些配置

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第22张图片

观察数据库nacos中的数据库表 config_info , 如下

springcloud+dubbo+nacos搭建(nacos使用mysql存储)_第23张图片

 

你可能感兴趣的:(Spring,Cloud,Alibaba,springcloud,dubbo,nacos)