Spring Cloud

Nacos配置中心和服务的注册发现

2020-11-13  本文已影响0人  牛初九

在上一篇中,我们已经把Nacos的集群搭建好了,那么既然已经搭建好了,就要在咱们的项目中去使用。Nacos既可以做配置中心,也可以做注册中心。我们先来看看在项目中如何使用Nacos做配置中心。

Nacos配置中心

在项目中使用Nacos做配置中心还是比较简单的,我们先创建SpringBoot项目,然后引入nacos-config的jar包,具体如下:

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

如果你不想使用SpringBoot默认的nacos-config版本,也可以指定版本号。

首先,我们进入到nacos的管理后台,第一步要创建命名空间,如图:


image-20201104155920161.png

我们创建了user的服务配置,以后user相关的微服务都在这个命名空间中拉取配置。我们点击保存,命名空间的id会自动生成,这个id是十分重要的,我们要在项目中配置这个id。命名空间创建好以后,我们再创建配置文件,


image-20201104160412542.png
在配置列表中,我们先选中刚才新建的命名空间:user服务配置。然后再点击新建,我的截图中已经把user-provider的配置文件创建好了。我们可以看一下如何新建,如图:
image-20201104161632192.png

其中Data ID我们叫做user-provider,group我们用来区分本地环境、测试环境、生产环境。配置格式我们选择yaml,内容我们先配置一个username看看能不能生效。

然后在resources目录下创建bootstrap.yml,这个bootstrap.yml和application.yml是不一样的,它优先加载于application.yml,大家一定要注意他们的区别。我们要在bootstrap.yml文件中,要配置nacos的地址、命名空间、文件名等信息,具体如下:

spring:
  cloud:
    nacos:
      server-addr: nacos-host:80
      config:
        file-extension: yml
        name: user-provider
        group: ${spring.profiles.active}
        namespace: e5aebd28-1c15-4991-a36e-0865bb5af930
  application:
    name: user-provider

到这里,在项目中使用nacos做配置中心就搭建好了。我们在项目当中写个属性类,测试一下,看看能不能取到值。

@RefreshScope
@Setter@Getter
@Configuration
public class DatabaseConfig {

    @Value("${username}")
    private String username;
    @Value("${server.port}")
    private String port;
}

我们在写个controller,把变量的值打印出来,如下:

@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private DatabaseConfig databaseConfig;


    @RequestMapping("config")
    public String config() {
        return databaseConfig.getUsername()+":"+databaseConfig.getPort();
    }
}

我们将username和port两个变量打印出来。好了,程序相关的部分就都写好了,然后,我们添加项目启动参数,如图:

image-20201105102408670.png

好了,我们现在启动项目,并且在浏览器中访问我们刚才写的controller,浏览器返回的结果如下:

user:8080

返回结果没有问题。然后我们再去nacos管理后台将user改成tom,项目不重启,再看看返回的结果,如图:


image-20201105110025531.png

确认发布以后,我们刷新一下浏览器,

tom:8080

我们并没有重启项目,但是返回的结果变成了tom。怎么样?使用nacos做配置中心还是比较好用的吧~

Nacos注册中心

通常情况下,我们一般会选择Zookeeper、Eureka做注册中心,其实Nacos也是可以做注册中心的。既然我们项目使用了Nacos做配置中心,那么使用Nacos做注册中心也是非常好的选择。下面让我们看看在项目中如何使用Nacos做注册中心。

首先,还是在项目中引入Nacos注册中心的jar包,如下:

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

我们引入了nacos-discovery的jar包,如果您不想使用默认的版本,可以指定需要引入的版本。

然后,我们就要配置Nacos注册中心的地址了,通常情况下,我们是在application.yml文件中进行配置。但是,这次我们使用了Nacos做配置中心,就可以在Nacos的管理后台进行配置了,如下:

username: tom
spring:
  cloud:
    nacos:
      discovery:
        server-addr: nacos-host:80
        namespace: e5aebd28-1c15-4991-a36e-0865bb5af930
        group: ${spring.profiles.active}

最后,我们在项目的启动类中添加@EnableDiscoveryClient的注解,如下:

@SpringBootApplication
@EnableDiscoveryClient
public class UserProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserProviderApplication.class, args);
    }
}

好了,到这里,服务提供者的配置以及代码上的改动都调整完毕了,我们启动一下项目,然后去Nacos管理后台看看服务是否已经注册到Nacos当中。

image-20201105113948039.png

我们在Nacos管理后台选择服务列表菜单,可以看到我们启动的项目已经注册到nacos中了。如果我们再启动一个服务提供者会是什么样子呢?我们刚启动的项目指定的端口是8080,我们再启动一个项目,将端口指定为8081,看看服务列表是什么样子。


image-20201110090555246.png

我们看到实例数由原来的1变为了2。说明我们的user-provider服务有了两个,我们再点右边的详情看一下,


image-20201110090713954.png

服务的详情以及具体的实例都给我们列了出来,我们还可以编辑和下线具体的实例,这个我们后面再介绍。

好了,到这里,服务提供者的就搭建好了,我们分别访问两个服务提供者的具体连接得到的结果如下:

# http://localhost:8080/user/config
tom:8080

# http://localhost:8081/user/config
tom:8081

接下来,我们再看看服务的消费者如何搭建。我们新建一个SpringBoot项目user-consumer,这个项目我们同样使用Nacos作为配置中心,而且要从Nacos这个注册中心获取服务列表,所以引入jar包如下:

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

然后在bootstrap.yml中,填写nacos配置中心的相关配置,这个和前面的配置的差不多的,只需要改一下相应的文件名称就可以了。

spring:
  cloud:
    nacos:
      server-addr: nacos-host:80
      config:
        file-extension: yml
        name: user-consumer
        group: ${spring.profiles.active}
        namespace: e5aebd28-1c15-4991-a36e-0865bb5af930
  application:
    name: user-consumer

然后,我们再去Nacos管理后台添加user-consumer的配置,如图:


image-20201110091827535.png

配置的部分就到这里了,然后再去启动类中,添加@EnableDiscoveryClient注解,如下:

@SpringBootApplication
@EnableDiscoveryClient
public class UserConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserConsumerApplication.class, args);
    }
}

最后,我们写个Controller,从Nacos获取服务提供者的地址,并调用服务提供者,如下:

@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @RequestMapping("consumer")
    public String consumer() {
        ServiceInstance provider = loadBalancerClient.choose("user-provider");
        String url = "http://"+provider.getHost()+":"+provider.getPort()+"/user/config";

        RestTemplate restTemp = new RestTemplate();
        String result = restTemp.getForObject(url, String.class);

        return result;
    }
}

最后,我们配置项目启动,设置spring.profiles.active=local,并且指定端口为9090,如图:


image-20201110094714366.png

最后,我们启动项目,访问http://localhost:9090/user/consumer,访问结果如下:

tom:8080

很明显,我们调用到了8080端口的服务提供者,我们再刷新一下,看看返回结果,

tom:8081

这次又调用到了8081端口的服务提供者,我们多次刷新,发现它会在8080和8081之间切换,这说明我们的负载均衡策略应该是轮询。

使用Feign完成服务的调用

上面的例子中,我们使用的是LoadBalancerClient完成服务的调用,接下来,我们分别看看Feign和Ribbon怎么调用服务。我们先来看看Feign,要使用Feign完成服务的调用,先要引入Feign的jar包,如下:

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-openfeign</artifactId>
 <version>2.2.2.RELEASE</version>
</dependency>

然后再启动类上添加@EnableFeignClients的注解,如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class UserConsumerApplication {
 public static void main(String[] args) {
 SpringApplication.run(UserConsumerApplication.class, args);
 }
}

接下来,我们写一个interface来完成feign的服务调用和熔断,如下:

@FeignClient(name = "user-provider",fallback = UserServiceFallback.class)
public interface UserService {
 @RequestMapping("/user/config")
 String config();
}

我们再来看看熔断实现类UserServiceFallback的具体内容,如下:

@Service
public class UserServiceFallback implements UserService {
 @Override
 public String config() {
 return "user-fallback";
 }
}

Feign的接口和熔断的实现类都写好了,但是这还不算完,要使熔断生效,还要添加额外的配置,我们直接去nacos管理后台去配置,进入到user-consumer的配置中,添加如下配置:

feign:
 hystrix:
 enabled: true</pre>

最后,我们在controller中,调用UserService接口,如下:

@Autowired
private UserService userService;
​
@RequestMapping("consumer-feign")
public String userService() {
 String result = userService.config();
​
 return result;
}

我们访问一下http://localhost:9090/user/consumer-feign,看看返回的结果。如下:

tom:8080
tom:8081

返回的结果和前面是一样的,我们不断的刷新,它也会在8080和8081之间轮询。

使用Ribbon完成服务的调用

同样,我们也可以使用Ribbon完成服务的调用,Ribbon和RestTemplate在内部是紧密结合的。我们只需要将RestTemplate实例化,并添加@LoadBalanced注解就可以了,如下:

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

然后在,controller中,我们使用这个实例化好的RestTemplate,就可以了,具体实现如下:

@Autowired
private RestTemplate restTemplate;
​
@RequestMapping("consumer-ribbon")
public String consumerribbon() {
 String url = "http://user-provider/user/config";
 String result = restTemplate.getForObject(url, String.class);
​
 return result;
}

我们重启项目,访问http://localhost:9090/user/consumer-ribbon,结果如下:

tom:8080
tom:8081

返回的结果和前面是一样的,我们不断的刷新,它也会在8080和8081之间轮询。

使用Nacos权重负载均衡

三种服务的调用方法都给大家介绍完了,但是,他们的负载均衡策略都是轮询,这有点不符合我们的要求,我们进入到Nacos的管理后台,调节一下服务的权重,如图:

image-20201110113637147.png
我们将8080接口的服务权重由1改为10,点击确认,再多次刷新一下我们的访问地址,发现服务的调用还是在8080和8081之间轮询。这是什么情况?这里就不和大家卖关子了,这是因为LoadBalancerClient、Feign和Ribbon3种方式,它们的底层都是使用Ribbon做负载均衡的,而Ribbon负载均衡默认使用的策略是ZoneAvoidanceRule,我们要修改Ribbon的默认策略,让它使用nacos的权重,那么该如何配置呢?

我们进入到nacos管理后台,修改user-consumer的配置,添加如下配置:

user-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

我们重启项目,调用我们之前的3个链接,调用哪个效果都是一样的,我们发现返回tom:8080的次数明显增多,说明Nacos服务的权重配置生效了。小伙伴们还可以将权重改成其他的值试一下。这里就不给大家演示了。

总结

Nacos的配置中心和服务注册中心就给大家介绍完了,还是很好用的,这为我们搭建微服务提供了另外一种选择。当然消费端的调用还是首推Feign+hystrix熔断的,功能很强大,小伙伴们在项目中多实践吧~

上一篇下一篇

猜你喜欢

热点阅读