04-Nacos服务注册中心应用实践

第二步:访问Nacos服务。

打开浏览器,输入http://localhost:8848/nacos地址,出现如下登陆页面:

在这里插入图片描述

其中,默认账号密码为nacos/nacos.

服务注册与调用入门(重点)

=======================================================================

业务描述


创建两个项目Module分别为服务提供者和服务消费者(假如已有则无需创建),两者都要注册到NacosServer中(这个server本质上就是一个web服务,端口默认为8848),然后服务提供者可以为服务消费者提供远端调用服务(例如支付服务为服务提供方,订单服务为服务消费方),如图所示:

在这里插入图片描述

生产者服务创建及注册


第一步:创建服务提供者工程(module名为sca-provider,假如已有则无需创建),继承parent工程(01-sca),其pom.xml文件内容如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

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

注意:服务名不要使用下划线(“_”),应使用横杠(“-”),这是规则。

第三步:创建启动类(假如已有则无需定义),关键代码如下:

package com.jt;

@SpringBootApplication

public class ProviderApplication {

public static void main(String[] args) {

SpringApplication.run(ProviderApplication.class, args);

}

}

第四步:启动启动类,然后刷先nacos服务,检测是否服务注册成功,如图所示:

在这里插入图片描述

第五步:停掉sca-provider服务,然后不断刷新nacos服务列表,检查服务的健康状态。

消费者服务发现及调用


第一步: 在sca-provider项目中创建服务提供方对象,基于此对象对外提供服务,例如:

package com.jt.provider.controller;

/**定义Controller对象(这个对象在spring mvc中给他的定义是handler),

  • 基于此对象处理客户端的请求*/

@RestController

public class ProviderController{

//@Value默认读取项目配置文件中配置的内容

//8080为没有读到server.port的值时,给定的默认值

@Value(“${server.port:8080}”)

private String server;

//http://localhost:8081/provider/echo/tedu

@GetMapping(“/provider/echo/{msg}”)

public String doRestEcho1(@PathVariable String msg){

return server+" say hello "+msg;

}

}

第二步:创建服务消费者工程(module名为sca-consumer,假如已有则无需创建),继承parent工程(01-sca),其pom.xml文件内容如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

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 #从哪里去查找服务

第四步:创建消费端启动类并实现服务消费,关键代码如下:

package com.jt;

@SpringBootApplication

public class ConsumerApplication {

public static void main(String[] args) {

SpringApplication.run(ConsumerApplication.class,args);

}

}

第五步:在sca-consumer启动类中添加如下方法,用于创建RestTemplate对象.

@Bean

public RestTemplate restTemplate(){//基于此对象实现远端服务调用

return new RestTemplate();

}

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

package com.jt.consumer.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.GetMapping;

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

import org.springframework.web.client.RestTemplate;

/**

  • 定义服务消费端Controller,在这个Controller对象

  • 的方法中实现对远端服务sca-provider的调用

*/

@RestController

public class ConsumerController {

/**

  • 从spring容器获取一个RestTemplate对象,

  • 基于此对象实现远端服务调用

*/

@Autowired

private RestTemplate restTemplate;

/**

  • 在此方法中通过一个RestTemplate对象调用远端sca-provider中的服务

  • @return

  • 访问此方法的url: http://localhost:8090/consumer/doRestEcho1

*/

@GetMapping(“/consumer/doRestEcho1”)

public String doRestEcho01(){

//1.定义要调用的远端服务的url

String url=“http://localhost:8081/provider/echo/8090”;

//2.基于restTemplate对象中的相关方法进行服务调用

return restTemplate.getForObject(url, String.class);

}

}

第七步:启动消费者服务,并在浏览器输入http://localhost:8090/consumer/doRestEcho1地址进行访问测试。

小节面试分析


  • 为什么要将服务注册到nacos?(为了更好的查找这些服务)

  • 在Nacos中服务提供者是如何向Nacos注册中心(Registry)续约的?(5秒心跳)

  • 对于Nacos服务来讲它是如何判定服务实例的状态?(检测心跳包,15,30)

  • 服务消费方是如何调用服务提供方的服务的?(RestTemplate)

服务负载均衡设计及实现(重点)

=========================================================================

业务描述


一个服务实例可以处理请求是有限的,假如服务实例的并发访问比较大,我们会启动多个服务实例,让这些服务实例采用一定策略均衡(轮询,权重,随机,hash等)的处理并发请求,在Nacos中服务的负载均衡(Nacos客户端负载均衡)是如何应用的?

LoadBalancerClient应用


LoadBalancerClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于特点算法实现负载均衡方式的调用,案例实现如下:

第一步:修改ConsumerController类,注入LoadBalancerClient对象,并添加doRestEcho2方法,然后进行服务访问.

@Autowired

private LoadBalancerClient loadBalancerClient;

@Value(“${spring.application.name:8090}”)

private String appName;

@GetMapping(“/consumer/doRestEcho02”)

public String doRestEcho02(){

ServiceInstance serviceInstance = loadBalancerClient.choose(“sca-provider”);

String url = String.format(“http://%s:%s/provider/echo/%s”,serviceInstance.getHost(),serviceInstance.getPort(),appName);

System.out.println(“request url:”+url);

return restTemplate.getForObject(url, String.class);

}

}

第二步:打开Idea服务启动配置,如图所示:

在这里插入图片描述

第三步:修改并发运行选项(假如没有找到这个选项我们需要通过搜索引擎基于组合查询的方法,去找到对应的解决方案,例如搜索 idea allow parallel run),如图所示:

在这里插入图片描述

第四步:修改sca-provider的配置文件端口,分别以8081,8082端口方式进行启动。

server:

port: 8082

spring:

application:

name: sca-provider

cloud:

nacos:

server-addr: localhost:8848

第五步:启动成功以后,访问nacos的服务列表,检测服务是否成功注册,如图所示:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第六步:启动sca-consumer项目模块,打开浏览器对consumer服务进行访问,访问时不断刷新,检测页面数据变化。

说明,这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。

@LoadBalanced


当使用RestTemplate进行远程服务调用时,假如需要负载均衡,还可以在RestTemplate对象构建时,使用@LoadBalanced对构建RestTemplate的方法进行修饰,例如在ConsumerApplication中构建名字为loadBalancedRestTemplate的RestTemplate对象:

@Bean

@LoadBalanced

public RestTemplate loadBalancedRestTemplate(){

return new RestTemplate();

}

在需要RestTemplate实现负载均衡调用的地方进行依赖注入.例如在ConsumerController类中添加loadBalancedRestTemplate属性

@Autowired

private RestTemplate loadBalancedRestTemplate;

接下来,可以在对应的服务端调用方的方法内,基于RestTemplate借助服务名进行服务调用, 例如:

@GetMapping(“/consumer/doRestEcho3”)

public String doRestEcho03(){

String url=String.format(“http://%s/provider/echo/%s”,“sca-provider”,appName);

//向服务提供方发起http请求,获取响应数据

return loadBalancedRestTemplate.getForObject(

url,//要请求的服务的地址

String.class);//String.class为请求服务的响应结果类型

}

RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,它的作用就是用于RestTemplate的负载均衡,LoadBalancerInterceptor将负载均衡的核心逻辑交给了loadBalancer,核心代码如下所示(了解):

public ClientHttpResponse intercept(final HttpRequest request,

final byte[] body, final ClientHttpRequestExecution execution) throws IOException {

final URI originalUri = request.getURI();

String serviceName = originalUri.getHost();

return this.loadBalancer.execute(serviceName,

requestFactory.createRequest(request, body, execution));

}

@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解,Spring会为其设置LoadBalancerInterceptor的拦截器。

Ribbon负载均衡策略(了解)


基于Ribbon方式的负载均衡,Netflix默认提供了七种负载均衡策略,对于SpringCloud Alibaba解决方案中又提供了NacosRule策略,默认的负载均衡策略是轮训策略。如图所示:

在这里插入图片描述

当系统提供的负载均衡策略不能满足我们需求时,我们还可以基于IRule接口自己定义策略.

小节面试分析


  • @Bean注解的作用?(一般用于配置类内部,描述相关方法,用于告诉spring此方法的返回值要交给spring管理,bean的名字默认为方法名,假如需要指定名字可以@Bean(“bean的名字”),最多的应用场景是整合第三方的资源-对象)

  • @Autowired注解的作用?(此注解用于描述属性,构造方法,set方法等,用于告诉spring框架,按找一定的规则为属性进行DI操作,默认按属性,方法参数类型查找对应的对象,假如只找到一个,则直接注入,类型多个时还会按照属性名或方法参数名进行值的注入,假如名字也不同,就出报错.)

  • Nacos中的负责均衡底层是如何实现的?(通过Ribbon实现,Ribbon中定义了一些负载均衡算法,然后基于这些算法从服务实例中获取一个实例为消费方法提供服务)

  • Ribbon 是什么?(Netflix公司提供的负载均衡客户端,一般应用于服务的消费方法)

  • Ribbon 可以解决什么问题? (基于负载均衡策略进行服务调用, 所有策略都会实现IRule接口)

  • Ribbon 内置的负载策略都有哪些?(8种,可以通过查看IRule接口的实现类进行分析)

  • @LoadBalanced的作用是什么?(描述RestTemplate对象,用于告诉Spring框架,在使用RestTempalte进行服务调用时,这个调用过程会被一个拦截器进行拦截,然后在拦截器内部,启动负载均衡策略。)

  • 我们可以自己定义负载均衡策略吗?(可以,基于IRule接口进行策略定义,也可以参考NacosRule进行实现)

基于Feign的远程服务调用(重点)

============================================================================

背景分析


服务消费方基于rest方式请求服务提供方的服务时,一种直接的方式就是自己拼接url,拼接参数然后实现服务调用,但每次服务调用都需要这样拼接,代码量复杂且不易维护,此时Feign诞生。

Feign是什么


Feign 是一种声明式Web服务客户端,底层封装了对Rest技术的应用,通过Feign可以简化服务消费方对远程服务提供方法的调用实现。如图所示:

在这里插入图片描述

Feign 最早是由 Netflix 公司进行维护的,后来 Netflix 不再对其进行维护,最终 Feign 由一些社区进行维护,更名为 OpenFeign。

Feign应用实践(掌握)


第一步:在服务消费方,添加项目依赖(SpringCloud团队基于OpenFeign研发了starter),代码如下:

org.springframework.cloud

spring-cloud-starter-openfeign

第二步:在启动类上添加@EnableFeignClients注解,代码如下:

@EnableFeignClients

@SpringBootApplication

public class ConsumerApplication {…}

第三步:定义Http请求API,基于此API借助OpenFeign访问远端服务,代码如下:

package com.jt.consumer.service;

@FeignClient(name=“sca-provider”)//sca-provider为服务提供者名称

public interface RemoteProviderService{

@GetMapping(“/provider/echo/{string}”)//前提是远端需要有这个服务

public String echoMessage(@PathVariable(“string”) String string);

}

其中,@FeignClient描述的接口底层会为其创建实现类。

第四步:创建FeignConsumerController中并添加feign访问,代码如下:

package com.jt.consumer.controller;

@RestController

@RequestMapping("/consumer/ ")

public class FeignConsumerController {

@Autowired

private RemoteProviderService remoteProviderService;

/*基于feign方式的服务调用/

@GetMapping(“/echo/{msg}”)

public String doFeignEcho(@PathVariable String msg){

//基于feign方式进行远端服务调用(前提是服务必须存在)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们:

目录:

二面蚂蚁金服(交叉面),已拿offer,Java岗定级阿里P6

Java面试核心知识点

一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!

二面蚂蚁金服(交叉面),已拿offer,Java岗定级阿里P6

Java面试核心知识点
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-gDZgH7sv-1712548287732)]

[外链图片转存中…(img-8irXkmlQ-1712548287732)]

[外链图片转存中…(img-rtx2XwIq-1712548287732)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们:

目录:

[外链图片转存中…(img-9Gwd25tN-1712548287733)]

Java面试核心知识点

一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!

[外链图片转存中…(img-DPrJ8yDu-1712548287733)]

Java面试核心知识点
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值