Nacos注册中心详解

Nacos注册中心详解

Nacos安装

官网地址: https://nacos.io/download/release-history/?spm=5238cd80.ee09dc2.0.0.63584522TOOcET

下载完成后直接解压 进入bin目录 输入cmd standlone的意思是单机启动
启动命令: startup.cmd -m standalone
在这里插入图片描述
浏览器搜索 http://localhost:8848/nacos
如果可以进入成功 那证明启动成功了
在这里插入图片描述

服务中心-服务注册

步骤:

  1. 引入服务发现依赖
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
     </dependencies>
  1. 配置Nacos地址
    创建application.properties 在里面写入
spring.application.name=service-order
server.port=8000

spring.cloud.nacos.server-addr=127.0.0.1:8848
  1. 启动微服务
package com.nie.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProductMainApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductMainApplication.class,args);

    }
}
  1. 查看注册中心效果
    在这里插入图片描述

服务中心-注册发现

步骤:

  1. 开启服务发现功能
package com.nie.product;

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

@SpringBootApplication
@EnableDiscoveryClient  //开启服务发现功能
public class ProductMainApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductMainApplication.class,args);

    }
}

  1. 测试服务发现API

编写测试案例

package com.nie.product;


import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;

import java.util.List;

@SpringBootTest
public class ProductTest {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Test
    void DiscoveryClientTest(){
        //获取service
        for (String service : discoveryClient.getServices()) {
            System.out.println("service = " + service);
            //获取ip加port
            List<ServiceInstance> instances = discoveryClient.getInstances(service);
            for (ServiceInstance instance : instances) {
                System.out.println("ip = " + instance.getHost()+",port="+instance.getPort());

            }
        }
    }
}

结果
在这里插入图片描述

注册中心-远程调用

下单场景
在这里插入图片描述
在这里插入图片描述

  1. 编写商品
package com.nie.product.bean;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class Product {
    private Long id;
    private BigDecimal price;
    private String productName;
    private int num;

}

编写controller层

package com.nie.product.controller;

import com.nie.product.bean.Product;
import com.nie.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/product/{id}")
    public Product getProduct(@PathVariable Long id) {
        Product product=productService.getProductByid(id);
        return product;
    }
}

编写商品service层

package com.nie.product.service;

import com.nie.product.bean.Product;

public interface ProductService {
    Product getProductByid(Long id);
}

package com.nie.product.service.Impl;

import com.nie.product.bean.Product;
import com.nie.product.service.ProductService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
public class ProductServiceImpl implements ProductService {

    public Product getProductByid(Long id) {
        Product product = new Product();
        product.setId(id);
        product.setPrice(new BigDecimal("100.00"));
        product.setProductName("西瓜"+id);
        product.setNum(3);

        return product;
    }
}

在这里插入图片描述
2. 编写订单
编写实体类

package com.nie.order.bean;

import lombok.Data;

import java.math.BigDecimal;
import java.util.List;


@Data
public class Order {
    private Long id;
    private BigDecimal totalAmount;
    private Long userId;
    private String nickName;
    private String address;
    private List<Object> productList;
}

编写controller

package com.nie.order.controller;

import com.nie.order.bean.Order;
import com.nie.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/create")
    public Order createOrder(@RequestParam("userId") Long userId,
                             @RequestParam("productId") Long productId){
        Order order = orderService.createOrder(productId,userId);
        return order;
    }
}

编写service

package com.nie.order.service;

import com.nie.order.bean.Order;

public interface OrderService {

    Order createOrder(Long productId ,Long userId);
}

package com.nie.order.service.Impl;

import com.nie.order.bean.Order;
import com.nie.order.service.OrderService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
public class OrderServiceImpl implements OrderService {


    public Order createOrder(Long productId , Long userId) {
        Order order = new Order();

        order.setId(1L);
        //TODO 总金额
        order.setTotalAmount(new BigDecimal("0"));
        order.setUserId(userId);
        order.setNickName("zhangsan");
        order.setAddress("小聂");
        //TODO 远程查询商品列表
        order.setProductList(null);

        return order;
    }
}

这时候发现productList 和TotalAmount我们需要远程调用product

如果我们把每个微服务的bean放在各自的包下,那会出现调用不到的情况,所以我们将他抽离到一个工程中
我们要在services中的pom文件里面写入这一句话

        <dependency>
            <groupId>com.nie</groupId>
            <artifactId>model</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

在这里插入图片描述
编写配置类 只要编写一次 之后使用直接注入即可

package com.nie.order.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OrderConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

远程调用的基本实现

我们可以写一个这个方法来远程访问 获取product数


    private Product getProduct(Long productId) {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        ServiceInstance serviceInstance = instances.get(0);
        String url="http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+productId;

        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }

完整的OrderServiceImpl代码为

package com.nie.order.service.Impl;

import com.nie.order.bean.Order;
import com.nie.order.service.OrderService;
import com.nie.product.bean.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.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    public Order createOrder(Long productId , Long userId) {
        Product product = getProduct(productId);

        Order order = new Order();
        order.setId(1L);
        //TODO 总金额
        order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));
        order.setUserId(userId);
        order.setNickName("zhangsan");
        order.setAddress("小聂");
        //TODO 远程查询商品列表
        order.setProductList(Arrays.asList(product));

        return order;
    }

    private Product getProduct(Long productId) {
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        ServiceInstance serviceInstance = instances.get(0);
        String url="http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/product/"+productId;

        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }
}

此时再次运行 结果为
在这里插入图片描述

注意 这时候我们会发现一个问题 我们不能每次就请求第一个服务器

所以我们使用负载均衡

@LoadBalanced注解

package com.nie.order.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OrderConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

我们只需要在配置类上加上@LoadBalanced

之后远程调用的实现就可以变成

    private Product getProduct1(Long productId) {
        String url="http://service-product/product/"+productId;
        Product product = restTemplate.getForObject(url, Product.class);
        return product;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值