微服务各组件整合

nacos

第一步,引入依赖

java 复制代码
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

第二步,增加配置

java 复制代码
spring:
  application:
    name: order
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

调用(手写一个负载均衡)

java 复制代码
@RequestMapping("/hello")
    public String hello(){
        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        ServiceInstance serviceInstance = instances.get(RandomUtil.randomInt(instances.size()));
        URI uri = serviceInstance.getUri();

        String url = uri + "/user-service/user/hello";
        log.info("调用地址:" + url);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET, null,
                new ParameterizedTypeReference<String>() {
                },
                String.class);

        String msg = result.getBody();
        log.info("接口返回:" + msg);
        return msg;
    }

openfeign

1、引入依赖

XML 复制代码
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

2、启动类上添加@EnableFeignClients

3、编写FeignClient

java 复制代码
package com.niuniu.product.feignclient;

import com.niuniu.product.model.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient(value = "order-service")
public interface OrderClient {
    @GetMapping(value = "/order-service/order/queryOrderByIds")
    List<Order> queryOrderByIds(@RequestParam("ids") List<String> ids);
}

4、调用

java 复制代码
package com.niuniu.product.controller;

import com.google.common.collect.Lists;
import com.niuniu.product.feignclient.OrderClient;
import com.niuniu.product.model.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping(value = "/product")
public class ProductController {
    @Autowired
    private OrderClient orderClient;
    /**
     * 调用user-service
     * @return
     */
    @RequestMapping("/testFeign")
    public List<Order> testFeign(){
        List<Order> orders = orderClient.queryOrderByIds(Lists.newArrayList("1", "2"));
        return orders;
    }
}

openfeign连接池

1、引入依赖

XML 复制代码
<!-- openfeign连接池 -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
        </dependency>

2、application.yml中开启

XML 复制代码
#openfeign连接池
feign:
  okhttp:
    enabled: true

3、debug查看效果

openfeign日志

openfeign有自己的日志级别

网关

1、引入依赖

XML 复制代码
<!-- 负载均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

        <!--用于被nacos发现该服务  被gateway发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- 网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

2、application.yaml配置

XML 复制代码
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order-service/**
        - id: product-service
          uri: lb://product-service
          predicates:
            - Path=/product-service/**
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/user-service/**
server:
  port: 8080
  servlet:
    context-path: /gateway-service

注意:

复制代码
如果直接访问product微服务的地址是http://localhost:8080/product-service/product/testFeign,
  • Path=/product-service/**。

如果 直接访问product微服务的地址是http://localhost:8086/product/testFeign,(省略掉了微服务名称)

  • Path=/product/**。

实现登录校验

配置管理

jwt登录功能

1、引入依赖

XML 复制代码
<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

2、Jwt工具类

java 复制代码
package com.niuniu.gateway.util;

import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {
    /**
     * 密钥
     */
    private static final String jwtToken = "niuniu";

    public static String createToken(Long userId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);
        JwtBuilder jwtBuilder = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, jwtToken) // 签发算法,密钥为jwtToken
                .setClaims(claims) // body数据,要唯一,自行设置
                .setIssuedAt(new Date()) // 设置签发时间
                .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 60 * 1000)); // 一天的有效时间
        String token = jwtBuilder.compact();
        return token;
    }

    public static Map<String, Object> checkToken(String token) {
        try {
            Jwt parse = Jwts.parser().setSigningKey(jwtToken).parse(token);
            return (Map<String, Object>) parse.getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * main方法验证一下工具类
     * @param args
     */
    public static void main(String[] args) {
        String token = JWTUtil.createToken(1000L);
        System.out.println("生成的token" + token);

        System.out.println("解析token" + JWTUtil.checkToken(token));
    }

}

3、登录,成功,返回token

java 复制代码
@GetMapping("/login")
    public ResponseEntity login(@RequestParam(name = "name") String name, @RequestParam(name = "password") String password){
        // 1、参数是否合法
        if (StringUtil.isEmpty(name) || StringUtil.isEmpty(password)) {
            return ResponseEntity.ok("用户名或密码不能为空");
        }
        // 2、用户是否存在
        User user = userMapper.login(name, password);
        // 3、用户不存在,登录失败
        if (user == null) {
            return ResponseEntity.ok("用户不存在");
        }
        // 4、用户存在,使用jwt生成token返给前端
        String token = JWTUtil.createToken(user.getId());
        // 5、将token放入redis
        redisTemplate.opsForValue().set("token_" + user.getId(), token);


        return ResponseEntity.ok(token);
    }

jwt登录

1、用户登录,根据用户id生成token并返回给前端;

2、登录后的所有请求,都将token传递给后端;

3、后端拿到token,判断是否登录(把token转成用户id),登录是否失效(使用redis缓存)。

将登录的用户信息传递到微服务

1、登录生成token;

2、在gateway微服务里写一个过滤器,校验token。

校验通过,保存用户信息到请求头(将token转成用户id);

校验不通过,终止请求。

3、写拦截器从请求头中取出用户信息保存到ThreadLocal。(拦截器放到common模块,供所有需要的微服务引用)

4、在业务处理过程中就可以从ThreadLocal中取到用户信息。

配置管理

相关推荐
IT 青年3 小时前
信息安全工程师(68)可信计算技术与应用
网络空间安全·信息安全工程师·1024程序员节·可信计算技术与应用
zaim11 天前
计算机的错误计算(一百五十六)
matlab·1024程序员节·双曲反余切·反双曲余切·acoth
惜.己1 天前
Jmeter中的前置处理器(二)
测试工具·jmeter·1024程序员节
惜.己1 天前
Jmeter中的监听器(二)
测试工具·jmeter·1024程序员节
三月七(爱看动漫的程序员)2 天前
LM2 : A Simple Society of Language Models Solves Complex Reasoning
人工智能·gpt·语言模型·自然语言处理·chatgpt·langchain·1024程序员节
惜.己2 天前
Jmeter中的监听器(四)
测试工具·jmeter·1024程序员节
惜.己2 天前
Jmeter中的前置处理器(一)
测试工具·jmeter·1024程序员节
lzb_kkk2 天前
【JavaEE】文件io
java·开发语言·java-ee·1024程序员节
KKK3号2 天前
Verilog HDL学习笔记
嵌入式硬件·fpga开发·verilog hdl·1024程序员节