在微服务架构中,注册中心是最核心的基础服务之一
服务提供者 ---生产者
服务消费者
服务发现与注册
它们之间的关系大致如下:
1.各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。
2.服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。
3.各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。
4.微服务网络地址发送变化(例如实例增加或IP变动等)时,会重新注册到注册中心。这样,服务消费者就无需人工修改提供者的网络地址了。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速
实现动态服务发现、服务配置、服务元数据及流量管理。
从上面的介绍就可以看出,nacos的作用就是一个注册中心,用来管理注册上来的各个微服务
安装
下载win或linux版本
启动
win
startup.cmd -m standalone
linux
先进入解压的bin目录下
sh startup.sh -m standalone
访问
默认账号密码都是 nacos
基于 http://t.csdnimg.cn/iFbUc的继续配置
快速回顾:
上篇文章中 父级项目 demo01 子级 comm service 孙级 order product
comm 放置实体类 service 放置生产者和消费者
1.service的pom文件引入依赖
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
- </dependency>
2.在主启动类上添加nacos的开启注解(Order消费者的启动类上)
@EnableDiscoveryClient // 当前的微服务是可以被nacos发现的
3. 在application.properties添加nacos的配置
a.设置微服务的名字
b.设置端口号
c.添加到注册中心,将该服务交给注册中心去管理
spring.application.name=order server.port=8081 #设置注册中心的地址 spring.cloud.nacos.discovery.server-addr=localhost:8848
对product进行复制,命名product1
完成如上配置后启动消费者与两个生产者

通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上 进行执行。
根据负载均衡发生位置的不同,一般分为服务端负载均衡和客户端负载均衡。
服务端负载均衡指的是发生在服务提供者一方,比如常见的nginx负载均衡
而客户端负载均衡指的是发生在服务请求的一方,也就是在发送请求之前已经选好了由哪个实例处理请求。
order 的pom引入依赖
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-loadbalancerartifactId>
- dependency>
- package com.example.config;
-
- import org.springframework.cloud.client.ServiceInstance;
- import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
- import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
- import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
- import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
- import org.springframework.context.annotation.Bean;
- import org.springframework.core.env.Environment;
-
- public class LoadBalancerConfig {
- @Bean
- ReactorLoadBalancer
randomLoadBalancer(Environment environment, - LoadBalancerClientFactory loadBalancerClientFactory) {
- String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); //loadbalancer.client.name
- // 对应的需要进行负载均衡的名字是什么
- System.out.println("======"+name);
- // product
- return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
- }
- }
- package com.order;
-
- import com.order.config.LoadBalancerConfig;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
- import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
- import org.springframework.context.annotation.Bean;
- import org.springframework.web.client.RestTemplate;
-
- @SpringBootApplication
- @LoadBalancerClients(
- defaultConfiguration = LoadBalancerConfig.class
- // product 会使用这个策略
- // @LoadBalancerClient(value = "product",configuration= LoadBalancerConfig.class)
- )
- public class OrderAppliaction {
- public static void main(String[] args) {
- SpringApplication.run(OrderAppliaction.class);
- }
-
- @Bean
-
- // @LoadBalanced
- public RestTemplate getRestTemplate(){
- return new RestTemplate();
- }
- }
SpirngCloud 中,默认是使用HTTP进行微服务间通信,其中最常用的有两种实现形式

直接使用 RestTemplate , Url写死
拼接url的方式
- @Resource
- private LoadBalancerClient loadBalancerClient;
- @Override
- public boolean addOrder(Integer pid) {
- ServiceInstance choose = loadBalancerClient.choose("product");
- String requestMsg = "方式二 GET 请求 RibbonServer";
- String url = String.format("http://%s:%s", choose.getHost(), choose.getPort() + "/pro/t-product/findById/"+pid);
- TProduct forObject = restTemplate.getForObject(url, TProduct.class);
- System.out.println(forObject);
- //添加订单
- if(forObject.getKucun()>0){
- //添加订单
- TOrder oreder=new TOrder();
- oreder.setNum(1);
- oreder.setPid(pid);
- oreder.setUid(1);
- boolean save = this.save(oreder);
- return save;
- //oreder.se
- }
- return false;
- }
利用 LoadBalancerClient 通过应用名获取 url,然后再使用 RestTemplate 请求
使用DiscoveryClient拼接url
- @Resource
- private DiscoveryClient discoveryClient;
- @GetMapping("addOrder/{pid}")
- public Result addOrder(@PathVariable("pid") Integer pid){
- List<ServiceInstance> serviceId = discoveryClient.getInstances("product");
- //如果有俩相同的微服务 不能定死是第一个 不然就没有任何的意义
- //随机产生数字
- int i = new Random().nextInt(serviceId.size());
- System.out.println("服务******"+i);
- ServiceInstance instance = serviceId.get(i);
- // id username productname
- Order order=new Order();
- order.setId(1);
- order.setUsername("于永利");
- System.out.println("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid);
- //商品的名字
- Result result= restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/getById/"+pid,Result.class);
- ObjectMapper objectMapper=new ObjectMapper();
- Product pro = objectMapper.convertValue(result.getT(), Product.class);
- //jackson
- //HashMap<String,String> product=(HashMap) result.getT();
- order.setProductname(pro.getName());
- return new Result(order);
-
-
- }

OpenFeign默认的负载均衡规则是轮循
- <!--使用openFeign-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
@EnableFeignClients

@FeignClient

service接口:
如果有异常 回滚到哪一个类里面
- @FeignClient(value="product",fallback = TOrderServiceImpl.class)
- public interface ITOrderService{
- }
service的实现类
- @Service
- public class TOrderServiceImpl implements ITOrderService {
-
-
- @Override
- public TProduct addOrder(Integer pid) {
- System.out.println("你调用我了吗");
- if(pid==0){
- System.out.println("出错啦!!!!");
- }
- return null;
- }
- }

加jar
- <!-- -->
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
- </dependency>
开启openfeign对sentinel的支持
(在application.properties中编写)
feign.sentinel.enabled=true