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;}
}


相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...