一.概念:
- Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
- Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理
- Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施
- 案例git仓库地址:https://gitee.com/xiaozunzun/load-balanced-distributed.git
二.下载安装配置
- 下载了nacos和jdk
- 将压缩包拖进来
-
在root根目录下解压缩jdk指定到usr/local/目录下(注意C是大写)
-
tar -zxf jdk-8u121-linux-x64.tar.gz -C /usr/local/
- 然后去配置环境变量
-
[root@localhost ~]# vim /etc/profile
-
export JAVA_HOME=/usr/local/jdk1.8.0_121 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
- 在这个文件里面配好环境变量之后,保存退出
- 10点半左右的视频
- 但是由于之前的jdk版本问题,又重新安装了一个jdk版本,热庵后我们一样的解压方式,现在,需要改一下环境变量(改一下版本)
-
export JAVA_HOME=/usr/local/jdk1.8.0_221 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
-
然后,保存配置
-
source /etc/profile
-
然后现在解压缩nacos
-
cd /usr/local/nacos/bin
./startup.sh -m standalone
-
tail -f /usr/local/nacos/logs/start.out
- 出现下面这样,代表服务启动成功
- 然后就可以去可视化界面登录了(和以前mq一样)
- http://192.168.8.171:8848/nacos 自己的地址,默认端口8848
- 就可以跳转到下面这个界面,然后登录,账号密码默认nacos
- 登录成功可以看到这样的界面
然后我们回到idea
- 现在是在产品里面加入依赖
-
<!--nacos客户端--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
- 产品启动类当中加入nacos客户端注解
-
@EnableDiscoveryClient//nacos客户端
- yml文件里面配置
-
#nacos 地址 cloud: nacos: discovery: server-addr: 192.168.8.171:8848
- 然后启动产品启动类,观察nacos可视化界面客户端是否有了产品模块的服务
- 然后,同样的方式,将订单的服务也加上去
- 现在订单controller里面,将原来静态发的请求,现在改为动态的从注册中心nacos中取
-
package com.pro.controller; import com.alibaba.fastjson.JSON; import com.pro.domain.Order; import com.pro.domain.Product; import com.pro.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; 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; @RestController public class OrderController { @Autowired private OrderService orderService; @Autowired private RestTemplate restTemplate; @Autowired private DiscoveryClient discoveryClient; @GetMapping("/order/prod/{pid}") public Order order(@PathVariable("pid") Integer pid){ List<ServiceInstance> instances = discoveryClient.getInstances("service-product"); ServiceInstance instance = instances.get(0); Product product = restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/"+pid,Product.class); //向订单模块发了一个请求,根据ID查询产品信息 // Product product = restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class); //创建订单 Order order = new Order(); order.setUid(1); order.setUname("小俊的订单"); order.setPid(pid); order.setPname(product.getPname()); order.setPrice(product.getPrice()); order.setNumber(1); orderService.createOrder(order); System.out.println("订单创建成功!信息为:"+ JSON.toJSONString(order)); return order; } }
负载均衡
从上面的描述我们可以看出, 客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从Eureka服务注册中心获取的。在Spring Cloud中我们如果想要使用客户端负载均衡,方法很简单,开启 @LoadBalanced
注解即可,这样客户端在发起请求的时候会先自行选择一个服务端,向该服务端发起请求,从而实现负载均衡。
- 客户端负载均衡
- spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这就是客户端负载均衡;即在客户端就进行负载均衡算法分配。
- copy一个product,相当于两台机器启动了相同的product服务
- 观察到product实例数有两个了,相当于两台机器集群成功
- postman测试
- 随机分配请求给集群当中的机器
- 测试负载均衡成功
- 但是我们不应该自己写随机数,而是应该真正的实现负载均衡
-
底层ribbon已经帮我们实现好了
- 我们只要加上这个注解就好了
- 加入配置
-
#指定使用哪种负载均衡策略:ribbon.并且指定对哪个服务实现负载均衡策略:service-product service-product: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
-
服务端负载均衡
fegin的概念和使用
-
概念
-
Feign旨在是编写Java Http客户端变得更加容易。
之前使用Ribbon+RestTemplate时,利用RESTTemplate请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,有偶遇对于服务依赖的调用可能不止一处,往往一个借口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务借口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon是,自动封装服务调用客户端的开发量。
-
使用和效果
- 在order里面导入依赖
-
<!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
- 订单启动类加上注解
-
@EnableFeignClients
- 加上productService接口
-
package com.pro.service; import com.pro.domain.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(value = "service-product") public interface ProductService { @GetMapping("/product/{pid}") public Product product(@PathVariable("pid") Integer pid);//这个接口的方法名可以和product里面的不一样 }
- 控制层调用接口里面的方法,实现远程调用
- 用了feign之后(restful风格),我们感觉就好像是在调用自己业务层的方法一样,目的就是让看不出来调用的是远程的服务。