上节讲的Nacos做SpringBoot项目的配置中心以及服务发现,并不好用。不能自动服务注册以及配置非常难用(也可能是我没找到便捷的方法),然后就将SpringCloud版本的集成操作一下(为后面学习消息队列RabbitMQ(也可能是RocketMQ)以及Seata做铺垫)。集成了一天,小细节很难发现,我等菜鸡一定要注意约定的力量。

下面基于Nacos服务已经启动的基础上,所以下载Nacos点击这里,zip是windows的tar.gz是linux的,也可以下载源码自行构建。

官方文档https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

首先上一下项目构成

然后POM版本依赖,这里也困扰好久,一直都注册不上去后来查看很多文档才知道要加入Cloud的依赖,官方文档又没讲。

这个项目所有公共依赖都在主POM中所以子模块中是没有依赖的。

1.要注意的是dependencyManagement中的依赖

2.SpringBoot版本还是不要大于2.2,nacos-config依赖是Nacos做配置中心要使用的依赖,nacos-discovery依赖是Nacos做服务注册发现要使用的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.xiaohe</groupId>
    <artifactId>seata-mq</artifactId>
    <version>10.01.01</version>
    <name>seata-mq</name>
    <packaging>pom</packaging>

    <properties>
        <test.project.version>10.01.01</test.project.version>
        <java.version>1.8</java.version>
        <nacos.config.vsersion>0.2.1.RELEASE</nacos.config.vsersion>
        <fastjson.version>1.1.28</fastjson.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <spring-cloud-alibaba.version>0.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <modules>
        <module>seata-mq-one</module>
        <module>seata-mq-two</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--SpringCloud Alibaba-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- spring aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- nacos配置依赖引入的是springcloud的nacos依赖所以上面要加入springcloud的依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${nacos.config.vsersion}</version>
        </dependency>
        <!-- 服务发现依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${nacos.config.vsersion}</version>
        </dependency>
        <!-- feign远程调用依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

整合Nacos要有关于Nacos配置的配置文件bootstrap.properties,要注意使用默认的命名空间就别写namespace=public了,这个搞得我崩溃。文件后缀也是要注意的是Nacos里面要将dataID打全!我这里是seata-mq-dev.yaml

#指定开发环境
spring.profiles.active=dev
#服务器地址
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
#如果要用默认Public命名空间,就他妈别写,要不然他妈的一直读不到
#spring.cloud.nacos.config.namespace=ffcbccbd-667a-4b2e-bc05-695e598af54a
#指定配置群组 --如果是DEFAULT_GROUP组 则可以省略群组配置
spring.cloud.nacos.config.group=DEFAULT_GROUP
#文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
spring.cloud.nacos.config.prefix=seata-mq
#指定文件后缀
spring.cloud.nacos.config.file-extension=yaml

要开启服务注册与发现加入discovery依赖之后在application.yml中加入服务发现地址

server:
  port: 8080

spring:
  application:
    name: seata-mq-one
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
#为了测试服务增加了Feign,默认熔断关闭这个配置开启熔断
feign:
  hystrix:
    enabled: true

以上配置不要落下,下面开始贴Application启动类,喜欢将解释放入代码注释中,能复制坚决不多打一个字!!!O(∩_∩)O哈哈~

import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;


@Slf4j
//这里要将默认数据源关闭,因为暂时没有配置。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//启用服务发现注解
@EnableDiscoveryClient
//Feign开启注解,basePackages和value功能相同,随意一个都可以。里面是feign扫描包路径
@EnableFeignClients(basePackages = {"com.xiaohe"},value = {"com.xiaohe"})
public class SeataMqTwoApplication {

    public static void main(String[] args) {
        log.info("seata-mq-two准备启动");
        SpringApplication.run(SeataMqTwoApplication.class, args);
    }

}

然后成果

服务注册发现

配置中心

为了检测是否读取了配置以及feign的调用是否可用,写了一个控制类进行检测代码如下

import com.xiaohe.seatamqtwo.feign.TwoClient;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/config")
public class TestController {

    //调用的two的feign接口client
    @Autowired
    private TwoClient twoClient;
    //这里直接用value就可以了,同样的:后面是默认值
    @Value("${test.msg:aYouMeiNaDao}")
    private String username;

    @GetMapping("/getMsg")
    public String getMsg(){
        System.out.println("msg内容是: "+username);
        return username;
    }
    //这里远程调用two服务的对外提供接口
    @GetMapping("/twoSayHello")
    public String twoSayHello(@RequestParam String name){
        return twoClient.twoSayHello(name);
    }
}

运行情况

顺带贴一下Feign的代码,作以记录(这里偷懒将接口以及实现放到了一个微服务中,实际项目中应该抽象与实现分离开来,调用方只依赖服务提供方API模块。面向接口编程)

1、定义一个远程调用接口

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(
        value="seata-mq-two",
        fallback = TwoClientFallback.class
)
public interface TwoClient {

    @GetMapping("/twoSayHello")
    String twoSayHello(@RequestParam String name);
}

2、定义实现类

import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AllArgsConstructor
public class TwoClientImpl implements TwoClient{


    @Override
    public String twoSayHello(String name) {
        return "hello,"+name+"! this is two client. ";
    }
}

3、定义熔断

import org.springframework.stereotype.Component;

@Component
public class TwoClientFallback implements TwoClient{

    @Override
    public String twoSayHello(String name) {
        return "connection fail";
    }
}

仓库地址:https://github.com/johnxiaohe/SpringCloud-Seata-Mq

有疑问或者修正的地方请留言,谢谢。