SpringCloudAlibaba学习-从Nacos开始

为什么要用Spring Cloud Alibaba

Spring Cloud是当下最为流行的微服务套件。它的技术组件集众家之长,Eureka、Zuul等都是依赖于Netflix的。这也导致了它受制于第三方厂商。比如Zuul目前宣布停止维护,Eureka2.x宣布闭源不允许使用,而且原生的Spring Cloud引入国内后,产生了一些水土不服的情况,比如config默认将配置文件存储在Github上,且没有维护界面。这都为国内使用带来了一些麻烦。而Spring Cloud Alibaba就结合国内的一些实际使用情况,解决了这些麻烦,同时扩展了功能,实现了更加符合国内使用习惯的微服务架构。

我要如何入门?

我们上面提到,Eureka和Config两个官方服务,都出现了一些问题,导致目前使用困难。所以,我们就先从解决这两个痛点的Nacos入手。Nacos结合了Eureka作为服务发现的作用以及Config作为配置中心的作用,同时也提供了一个可视化的界面用于管理。所以将Nacos作为学习Spring Cloud Alibaba的学习切入点是比较合适的。

来写个小Demo吧

说得再多,也不如一个小Demo直白。下面我们要来写一个简单的Demo,一个生产者,一个消费者,两个微服务。然后用Nacos作为服务发现,下面我们就开始动手。

先建个父工程

首先我们在idea中建立一个空的Maven工程,命名为spring-cloud-nacos。然后我们需要去修改一下pom文件,添加一些依赖管理内容。这里我们先将它作为一个普通的父工程来处理,后面我们再来改造成Spring Cloud Alibaba的形式。

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springbootstart.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

这里我们先只引入基础的Spring Boot依赖,后面再进行改造

再来个生产者

在这个父工程下,新建一个Module,就叫nacos-provider-8010,作为生产者。新建好后,我们同样去修改pom文件,引入一些基础的依赖

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

然后我们来写一个简单的接口,模拟提供一个查询服务

首先是实体类

package com.akitsuki.entity;

import lombok.Data;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 15:22
 */
@Data
public class EntityInfo {

    private String entityId;
    private String info;
    private String sendTime;
}

然后是服务类

package com.akitsuki.service;

import com.akitsuki.entity.EntityInfo;
import org.springframework.stereotype.Service;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 15:23
 */
@Service
public class EntityInfoService {

    public EntityInfo queryEntityInfo(String entityId) {
        EntityInfo entityInfo = new EntityInfo();
        entityInfo.setEntityId(entityId);
        entityInfo.setInfo("Hello Nacos");
        entityInfo.setSendTime(String.valueOf(System.currentTimeMillis()));
        return entityInfo;
    }
}

最后是Controller

package com.akitsuki.controller;

import com.akitsuki.entity.EntityInfo;
import com.akitsuki.service.EntityInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 15:26
 */
@RestController
public class NacosProviderController {

    @Autowired
    private EntityInfoService entityInfoService;

    @GetMapping(value = "/entityInfo/{entityId}")
    public EntityInfo queryEntityInfo(@PathVariable("entityId") String entityId) {
        return entityInfoService.queryEntityInfo(entityId);
    }
}

最后别忘了启动类

package com.akitsuki;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 15:16
 */
@SpringBootApplication
public class NacosProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosProviderApplication.class);
    }
}

还有配置文件application.yml中指定启动端口

server:
  port: 8010

这样我们的简易生产者就做好了。启动起来试着访问一下

没问题,接口可以调用成功,说明这个简单的生产者可以正常工作。

接下来是消费者

有了生产者,还得有个消费者,用来模拟微服务之间的相互调用。我们在父工程下面再建立一个Module,就叫nacos-consumer-9000。同样的,按照生产者的方式,引入基本的依赖。这里我们就只写一个Controller用来调用就好

package com.akitsuki.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 16:43
 */
@RestController
public class EntityInfoController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/entityInfo/{entityId}")
    public String getEntityInfo(@PathVariable("entityId") String entityId) {
        String url = "http://localhost:8010/entityInfo/" + entityId;
        return restTemplate.getForEntity(url, String.class).getBody();
    }
}

试着启动消费者调用一下

看起来也没有问题,那么实际上到这里我们做的事情和Spring Cloud Alibaba半毛钱关系都没有,只是搭了两个架子而已。

接下来,我们就要着手改造了,让它真的成为一个Spring Cloud Alibaba的Demo。

来引入Nacos吧

终于要进入正题了,先来引入我们的Nacos作为注册中心吧。我们如果进入Nacos的官网,可以看到它会指引我们去Github进行下载。但由于众所周知的原因,这个下载实际很难达成。但我们依然有办法,那就是去Gitee进行下载。Gitee也有一份Nacos的代码,每天同步一次。所以我们可以认为基本和Github上面是一致的。

我们访问 https://gitee.com/mirrors/Nacos

由于我们是写小Demo,也不用考虑稳定性之类的东西,所以直接下载默认的develop分支代码,然后打开

看起来非常复杂,但其实我们可以不去管它。按照一些步骤来启动即可。

首先是maven打包

mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

打完包后,我们cd到 distribution/target/nacos-server-$version/nacos/bin目录下

然后我们以单机模式启动(这里我是windows系统所以用startup.cmd)

Nacos默认的端口是8848,我们可以在conf目录下的application.properties中修改server.port来进行修改,我这里修改成了8858。

startup.cmd -m standalone

nice,看到Nacos的字符画,心里顿时有了底。

由于Nacos自带了一个管理界面,所以我们试着访问看看 http://localhost:8858/nacos

我们用默认账号密码nacos/nacos登入

看起来非常管理系统的一个管理系统。里面大部分功能我们以后再来探究,现在主要看看服务管理。这里就是用来管理注册到Nacos的服务的

自然,现在是空的。既然Nacos也启动起来了,我们也要着手改造我们前面的生产者和消费者了。

开始改造吧

首先是我们的父工程,在依赖管理中,要加入spring-cloud的依赖,和spring-cloud-alibaba的依赖。

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2020.0.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

然后是我们的生产者,要引入服务发现的依赖

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

既然有了服务发现,那我们的服务也要有个名字。以及前面我们修改了Nacos的默认端口,所以我们这里也要重新指定服务发现服务的端口

server:
  port: 8010
spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8858
      config:
        server-addr: localhost:8858

对于生产者来说,这么多改造就足够了。可以把自己注册到Nacos就行

下面是消费者,同样,也要引入服务发现的依赖和负载均衡的依赖

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

然后,我们需要对RestTemplate进行一些改造,对其加上负载均衡的注解,这样它才能识别到我们用服务名的url。

package com.akitsuki.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 16:11
 */
@Component
public class BeanManagerConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

然后我们的请求url也要改一下,用服务名进行请求,而不是用ip+端口的方式进行请求。

package com.akitsuki.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author ziling.wang@hand-china.com
 * @date 2022/9/27 16:43
 */
@RestController
public class EntityInfoController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping(value = "/entityInfo/{entityId}")
    public String getEntityInfo(@PathVariable("entityId") String entityId) {
        String url = "http://nacos-provider/entityInfo/" + entityId;
        return restTemplate.getForEntity(url, String.class).getBody();
    }
}

同样,这里的配置文件也要加上相应的内容

server:
  port: 9000
spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8858
      config:
        server-addr: localhost:8858

好了,改造完毕!让我们启动服务看看吧

nacos的反应十分迅速,服务列表里面已经有我们的两个服务了

接下来我们试着访问一下订阅者的接口

很完美,能请求到数据,这就代表我们可以通过服务名来调用生产者的服务了。

到这里,我们的小Demo就算完成了,也算是开启了Spring Cloud Alibaba的学习之路。期间其实并没有这个文章看起来那么顺利,还是遇到了许多小问题。随着问题的不断解决,也是加深理解的一个过程。那么,就到这里吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值