Nacos注册中心和服务方式
创始人
2024-04-14 07:39:01
0

目录

 一、服务治理介绍

常见的注册中心

二、Nacos注册中心介绍

 三、运用Nacos搭建环境

四、DiscoveryClient实现负载均衡

五、Ribbon实现负载均衡

 六、基于Feign实现服务调用

七、Feign传参


 一、服务治理介绍

通过上一章的操作,我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址 (ip,端口)等硬编码到了代码中,这种做法存在许多问题:

  • 一旦服务提供者地址变化,就需要手工修改代码

  • 一旦是多个服务提供者,无法实现负载均衡功能

  • 一旦服务变得越来越多,人工维护调用关系困难

 为解决以上麻烦:就需要通过注册中心动态的实现服务治理。

常见的注册中心

Zookeeper zookeeper    是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式 应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用 配置项的管理等。

Eureka Eureka    是Springcloud Netflix中的重要组件,主要作用就是做服务注册和发现。但是现在已经闭 源

Consul Consul  是基于GO语言开发的开源工具,主要面向分布式,服务化的系统提供服务注册、服务发现 和配置管理的功能。Consul的功能都很实用,其中包括:服务注册/发现、健康检查、Key/Value 存储、多数据中心和分布式一致性保证等特性。Consul本身只是一个二进制的可执行文件,所以 安装和部署都非常简单,只需要从官网下载后,在执行对应的启动脚本即可。

 Nacos Nacos    是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它是 Spring Cloud Alibaba 组件之一,负责服务注册发现和服务配置,可以这样认为nacos=eureka+config。 


二、Nacos注册中心介绍

  Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速 实现动态服务发现、服务配置、服务元数据及流量管理。 从上面的介绍就可以看出,nacos的作用就是一个注册中心,用来管理注册上来的各个微服务。


 三、运用Nacos搭建环境

 接下来,我们就在现有的环境中加入nacos,并将我们的两个微服务注册上去。

 1.将下载的安装包(Nacos)在非中文目录下进行解压

 解压后找到bin目录下的startup.cmd 点击编辑,

 --->把   set MODE="cluster" 改为 set MODE="standalone"

 ----->保存编辑,在bin目录下加入cmd命令

 2.启动Nacos

重启命令:输入startup.cmd -m standalone

 3.登录Nacos账号 

 谷歌浏览器地址栏输入:http://localhost:8848/nacos/#/login

 注意这里用户名小写:nocas  密码与用户名一致

 4.添加相关依赖

对父模块添加代码


4.0.0com.zkingspringcloud-shop1.0-SNAPSHOTshop-common shop-usershop-productshop-orderpom1.8UTF-8UTF-82.3.2.RELEASEHoxton.SR92.2.6.RELEASEorg.springframework.bootspring-boot-dependencies${spring-boot.version}pomimport org.springframework.cloudspring-cloud-dependencies${spring-cloud.version}pomimportcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring-cloud-alibaba.version}pomimport

基础模块添加注册中心:


springcloud-shopcom.zking1.0-SNAPSHOT4.0.0shop-common



org.projectlomboklombokcom.alibabafastjson1.2.56mysqlmysql-connector-java5.1.44
com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery

5.配置文件 

spring:application:name: shop-orderspring:  cloud:nacos:discovery:server-addr: localhost:8848
server:port: 8090

6.运行时添加注解@EnableDiscoveryClient

package com.zking.shoporder;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableDiscoveryClient
@SpringBootApplication
public class ShopOrderApplication {public static void main(String[] args) {SpringApplication.run(ShopOrderApplication.class, args);}@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}

 最后启动所有微服务  查看服务列表

 


四、DiscoveryClient实现负载均衡

 如图操作:复制微服务 

 

 更新名字,快捷键(Alt+insert)添加port端口号8081-->最后使用

 启动该新添微服务

 

 

效果:

 

package com.zking.shoporder.controller;

import com.zking.model.Order;
import com.zking.model.Product;
import com.zking.model.User;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Random;

/**
 * @author小李飞刀
 * @site www.javaxl.com
 * @company xxx公司
 * @create  2022-11-20 23:30
 */
@RestController
@RequestMapping("/order")
public class OrderController_DiscoveryClient {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private  DiscoveryClient discoveryClient;

    @RequestMapping("/get/{uid}/{pid}")
    public Order get(@PathVariable("uid") Integer uid,
                     @PathVariable("pid") Integer pid){

//   通过服务名拿到这个节点的实例数
        List instances = discoveryClient.getInstances("shop-product");
        int index = new Random().nextInt(instances.size());
        ServiceInstance serviceInstance = instances.get(index);
        String url = serviceInstance.getHost() + ":" +
                serviceInstance.getPort();

        User user = restTemplate.getForObject("http://localhost:8070/user/get/" + uid, User.class);
        Product product = restTemplate.getForObject("http://"+url+"/product/get/" + pid, Product.class);
        Order order = new Order();
        order.setNumber(2);
        order.setOid(System.currentTimeMillis());
        order.setPid(pid);
        order.setPname(product.getPname());
        order.setPprice(product.getPprice() * order.getNumber());
        order.setUid(user.getUid());
        order.setUsername(user.getUsername());
        return order;
    }
}
 

package com.zking.shopproduct.controller;import com.zking.model.Product;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;/*** @author小李飞刀* @site www.javaxl.com* @company xxx公司* @create  2022-11-20 23:24*/
@RestController
@RequestMapping("/product")
public class ProductController {@RequestMapping("/get/{pid}")public Product get(@PathVariable("pid") Integer pid, HttpServletRequest request){System.out.println("======================="+request.getServerPort());Product p = new Product(pid, "元气奶茶", 36d, 36);return p;}}
package com.zking.shoporder;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;//@EnableDiscoveryClient
//@SpringBootApplication
public class ShopOrderApplication_DiscoveryClient {public static void main(String[] args) {SpringApplication.run(ShopOrderApplication_DiscoveryClient.class, args);}//    @LoadBalanced     DiscoveryClient这种方式,切记不要添加这个注解,否则会报错No instances available for localhost@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}

 

 

五、Ribbon实现负载均衡

package com.zking.shoporder;import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;//@EnableDiscoveryClient
//@SpringBootApplication
public class ShopOrderApplication_Ribbon {public static void main(String[] args) {SpringApplication.run(ShopOrderApplication_Ribbon.class, args);}@LoadBalanced@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}
 
package com.zking.shoporder.controller;import com.zking.model.Order;
import com.zking.model.Product;
import com.zking.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** @author lucy* @site www.javaxl.com* @company xxx公司* @create  2022-11-20 23:30*/@Slf4j
//@RestController
//@RequestMapping("/order")
public class OrderController_Ribbon {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/get/{uid}/{pid}")public Order get(@PathVariable("uid") Integer uid,@PathVariable("pid") Integer pid){log.info(">>客户下单,这时候要调用商品微服务查询商品信息");User user = restTemplate.getForObject("http://shop-user/user/get/" + uid, User.class);Product product = restTemplate.getForObject("http://shop-product/product/get/" + pid, Product.class);Order order = new Order();order.setNumber(2);order.setOid(System.currentTimeMillis());order.setPid(pid);order.setPname(product.getPname());order.setPprice(product.getPprice() * order.getNumber());order.setUid(user.getUid());order.setUsername(user.getUsername());return order;}
}


 六、基于Feign实现服务调用

 导入依赖

  


springcloud-shopcom.zking1.0-SNAPSHOT4.0.0shop-common



 org.springframework.cloudspring-cloud-starter-openfeignorg.projectlomboklombokcom.alibabafastjson1.2.56mysqlmysql-connector-java5.1.44com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery

OrderController_Feign

package com.zking.shoporder.controller;import com.zking.model.Order;
import com.zking.model.Product;
import com.zking.model.User;
import com.zking.shoporder.Service.ProductService;
import lombok.extern.slf4j.Slf4j;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;
import java.util.Random;/*** @author    lucy* @site www.javaxl.com* @company xxx公司* @create  2022-11-20 23:30*/@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController_Feign {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@Autowiredprivate ProductService productService;@RequestMapping("/get/{uid}/{pid}")public Order get(@PathVariable("uid") Integer uid,@PathVariable("pid") Integer pid) {
//        用了注册中心以及@LoadBalanced(discoveryClient模式不需要@LoadBalanced),就不能用localhost:8070的方式远程调用,只能通过应用名shop-user的方式访问
//        java.lang.IllegalStateException: No instances available for localhost
//        User user = restTemplate.getForObject("http://localhost:8070/user/get/" + uid, User.class);
//        User user = restTemplate.getForObject("http://192.168.1.5:8070/user/get/" + uid, User.class);User user = restTemplate.getForObject("http://shop-user/user/get/" + uid, User.class);Product product = productService.get(pid);Order order = new Order();order.setNumber(2);order.setOid(System.currentTimeMillis());order.setPid(pid);order.setPname(product.getPname());order.setPprice(product.getPprice() * order.getNumber());order.setUid(user.getUid());order.setUsername(user.getUsername());return order;}
}

 ShopOrderApplication_Fegin

package com.zking.shoporder;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients //开启Fegin
public class ShopOrderApplication_Fegin {public static void main(String[] args) {SpringApplication.run(ShopOrderApplication_Fegin.class, args);}负载均衡添加
//    @LoadBalanced@Beanpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}



七、Feign传参

  ProductService

package com.zking.shoporder.Service;import com.zking.model.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletRequest;/*** @author 锦鲤* @site www.lucy.com* @company xxx公司* @create  2022-11-27 19:55* 帮助消费者  shop-order调用生产者shop-product*/@FeignClient("shop-product") //声明调用提供者的namepublic interface ProductService {@RequestMapping("/product/get/{pid}")public Product get(@PathVariable("pid") Integer pid);@RequestMapping("/findByParameter")public String findByParameter( @RequestParam("name")String name, @RequestParam("price")Double price);@RequestMapping("/findByParameter2")public String findByParameter2(@RequestParam("name") String name,@RequestParam("price") Double price);@RequestMapping("/findByPathVariable/{name}")public String findByPathVariable(@PathVariable("name") String name);@RequestMapping("/findByRequestBody")public Product findByRequestBody(Product product);}

 FeignClientController

package com.zking.shoporder.controller;import com.zking.model.Product;
import com.zking.shoporder.Service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@Slf4j
@RestController
@RequestMapping("/feignClient")
public class FeignClientController {@Autowiredprivate ProductService productService;@RequestMapping("/findByParameter")public String findByParameter(  @RequestParam("name")String name,  @RequestParam("price") Double price){log.info("服务消费者日志:{}",name);return productService.findByParameter(name,price);}@RequestMapping("/findByParameter2")public String findByParameter2(@RequestParam("name") String name,@RequestParam("price") Double price){log.info("服务消费者日志:{},{}",name,price);return productService.findByParameter2(name, price);}@RequestMapping("/findByPathVariable/{name}")public String findByPathVariable(@PathVariable("name") String name){log.info("服务消费者日志:{}",name);return productService.findByPathVariable(name);}@RequestMapping("/findByRequestBody")public Product findByRequestBody(Product product){log.info("服务消费者日志:{}",product.getPname());return productService.findByRequestBody(product);}
}

 FeignServerController

package com.zking.shopproduct.controller;import com.zking.model.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;@Slf4j
@RestController
@RequestMapping("/feignserver")
public class FeignServerController {@RequestMapping("/findByParameter")public String findByParameter(String name,Double price){log.info("服务提供者日志:{}",name);return "hello:"+name;}@RequestMapping("/findByParameter2")public String findByParameter2(@RequestParam("name") String name,@RequestParam("price") Double price){log.info("服务提供者日志:{},{}",name,price);return "hello:"+name+price;}@RequestMapping("/findByPathVariable/{name}")public String findByPathVariable(@PathVariable("name") String name){log.info("服务提供者日志:{}",name);return "hello:"+name;}@RequestMapping("/findByRequestBody")public Product findByRequestBody(@RequestBody Product product){log.info("服务提供者日志:{}",product.getPname());return product;}
}


相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...