微服务各组件整合

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中取到用户信息。

配置管理

相关推荐
学传打活10 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续3)
微信公众平台·1024程序员节·汉字·昆仑正义文化
学传打活15 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng16823 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心25 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055271 个月前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055271 个月前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝1 个月前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u0103055271 个月前
Java图像处理实战指南
人工智能·1024程序员节
u0103055271 个月前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u0103055271 个月前
Java实用类应用精讲
人工智能·1024程序员节