Nacos注册中心和服务消费方式

1.安装配置nacos以及实现服务支持

nacos简介

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速
实现动态服务发现、服务配置、服务元数据及流量管理。
从上面的介绍就可以看出,nacos的作用就是一个注册中心,用来管理注册上来的各个微服务。
nacos2.0.1版本: https://pan.baidu.com/s/1hXH5Eq3ZR1T1qZ0YOqD5Cg
提取码:8kb0

1.1:切换单体:
startup.cmd -m standalone

或者直接修改startup.cmd文件:set MODE="standalone"

1.2:访问nacos:
打开浏览器输入http://localhost:8848/nacos,即可访问服务, 默认密码是nacos/nacos
1.3:模块依赖:

<!--nacos客户端-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

1.4:在模块启动类上添加注解:@EnableDiscoveryClient

package com.xujie.shop_product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class ShopProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShopProductApplication.class, args);
    }

}

启动后查看nacos:
注:nacos中的服务名不能出现"_",这是nacos的格则(我出过这个错0.0)
在这里插入图片描述

实现服务调用的负载均衡

Ribbon实现负载均衡

package com.xujie.shop_order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
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);
    }

    @Bean
    @LoadBalanced  //使用ribbon方式实现负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

 log.info("客户下单,这时候要调用商品微服务查询商品信息");
        //定义微服务的服务名称,对应的是商品服务的双节点(8080和8081)
        String serverName="shop-product";
        log.info("远程调用地址为:{}","http://"+serverName+"/product/getOne/"+pid);
        Product product =restTemplate.getForObject(
                "http://"+serverName+"/product/getOne/"+pid,Product.class
        );

在这里插入图片描述

DiscoveryClient实现负载均衡

package com.xujie.shop_order.controller;

import com.alibaba.fastjson.JSON;
import com.xujie.common.model.Order;
import com.xujie.common.model.Product;
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 许缘
 * @company xxx公司
 * @create 2022-12-06  17:25
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class ordercontroller {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/test/{pid}")
    public Order createOrder(@PathVariable("pid") Integer pid){
        log.info("客户下单,这时候要调用商品微服务查询商品信息");
        //定义微服务的服务名称,对应的是商品服务的双节点(8080和8081)
        String serverName="shop-product";
        //获取当前微服务所对应的实例数
        List<ServiceInstance> instances = discoveryClient.getInstances(serverName);
        //使用随机挑选的方式获取服务实例
        int index = new Random().nextInt(instances.size());
        //根据挑选的服务下标获取具体的服务实例(ip+端口)
        ServiceInstance instance = instances.get(index);
        //拼接生产者的服务的地址
        String url="http://"+instance.getHost()+":"+instance.getPort();

        log.info("远程调用地址为:{}",url+"/product/getOne/"+pid);
        Product product =restTemplate.getForObject(
                url+"/product/getOne/"+pid,Product.class
        );
        log.info("查询结果:"+ JSON.toJSONString(product));
        //创建订单
        Order order = new Order();
        order.setOid(System.currentTimeMillis());
        order.setUid(12);
        order.setUsername("张三");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(product.getStock());
        return order;


    }
}

在这里插入图片描述

基于Feign实现服务调用

什么是Feign

Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务
一样简单, 只需要创建一个接口并添加一个注解即可。
Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果。

Feign的使用

pom.xml依赖:

<!--fegin组件-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

添加注解:@EnableFeignClients启用远程调用

package com.xujie.shop_order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableFeignClients //启用远程调用
@EnableDiscoveryClient
@SpringBootApplication
public class ShopOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShopOrderApplication.class, args);
    }

    @Bean
    //@LoadBalanced  //使用ribbon方式实现负载均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

接口:

package com.xujie.shop_order.service;

import com.xujie.common.model.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 许缘
 * @company xxx公司
 * @create 2022-12-07  14:39
 * @FeignClient:指定微服务的服务名称
 * shop-product === http://193.168.1.144:8081/
 */
@FeignClient("shop-product") //调用是哪个服务
public interface IProductService {
    /**
     *  http://193.168.1.144:8081/product/getOne/{pid}
     * @param pid
     * @return
     */
    @RequestMapping("/product/getOne/{pid}")
    Product getOne(@PathVariable("pid") Integer pid);

}

package com.xujie.shop_order.controller;

import com.alibaba.fastjson.JSON;
import com.xujie.common.model.Order;
import com.xujie.common.model.Product;
import com.xujie.shop_order.service.IProductService;
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 许缘
 * @company xxx公司
 * @create 2022-12-06  17:25
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class ordercontroller {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;
    /**
     * 相当于本地调用
     */
    @Autowired
    private IProductService productService;

    @RequestMapping("/test/{pid}")
    public Order createOrder(@PathVariable("pid") Integer pid){
        log.info("客户下单,这时候要调用商品微服务查询商品信息");
        Product product = productService.getOne(pid);
        log.info("查询结果:"+ JSON.toJSONString(product));
        //创建订单
        Order order = new Order();
        order.setOid(System.currentTimeMillis());
        order.setUid(12);
        order.setUsername("张三");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(product.getStock());
        return order;


    }
}

Feign参数传递

package com.xujie.shop_product.controller;

import com.xujie.common.model.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/feign")
public class FeignDemoController {
    @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")
    public String findByPathVariable(@PathVariable String name){
        log.info("服务提供者日志:{}",name);
        return "hello:"+name;
    }
    @RequestMapping("/findByRequestBody")
    public Product findByRequestBody(@RequestBody Product product){
        log.info("服务提供者日志:{}",product.getPname());
        return product;
    }
}

消费者:

package com.xujie.shop_order.service;

import com.xujie.common.model.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @author 许缘
 * @company xxx公司
 * @create 2022-12-07  15:14
 * 在这边必须按照生产者的传参要求传参
 * 调用生产者的方法时必须要加注解
 */
@FeignClient("shop-product")
public interface IFeignService {
    @RequestMapping("/feign/findByParameter")
     String findByParameter(@RequestParam("name") String name,
                            @RequestParam("price") Double price);
    @RequestMapping("/feign/findByParameter2")
     String findByParameter2(
            @RequestParam("name") String name,
            @RequestParam("price") Double price);
    @RequestMapping("/feign/findByPathVariable/{name}")
     String findByPathVariable(@PathVariable("name") String name);
    @RequestMapping("/feign/findByRequestBody")
     Product findByRequestBody(@RequestBody Product product);

}


controller可以不按照生产者的要求传参:

package com.xujie.shop_order.controller;

import com.alibaba.fastjson.JSON;
import com.xujie.common.model.Order;
import com.xujie.common.model.Product;
import com.xujie.shop_order.service.IFeignService;
import com.xujie.shop_order.service.IProductService;
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.*;
import org.springframework.web.client.RestTemplate;

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

/**
 * @author 许缘
 * @company xxx公司
 * @create 2022-12-06  17:25
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class ordercontroller {

    @Autowired
    private IFeignService feignService;

    @RequestMapping("/findByParameter")
    public String findByParameter(String name,Double price){
        return feignService.findByParameter(name,price);
    }
    @RequestMapping("/findByParameter2")
    public String findByParameter2(String name, Double price){
        return feignService.findByParameter2(name, price);
    }
    @RequestMapping("/findByPathVariable")
    public String findByPathVariable(String name){
        return feignService.findByPathVariable(name);
    }
    @RequestMapping("/findByRequestBody")
    public Product findByRequestBody(Product product){
        return feignService.findByRequestBody(product);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值