2110-微服务核心知识点及问题分析

文章目录

  • Day01~微服务架构入门
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课堂练习
    • 课后作业
  • Day02~Nacos注册中心入门
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day03~远程服务调用实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day04~Nacos配置中心应用实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day05-Sentinel 限流应用实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day06-Sentinel 进阶应用实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day07-Gateway 应用实践
    • 核心知识点
    • 常见问题分析
    • 常见BUG分析
    • 课后作业
  • Day08-Gateway 应用进阶实践
    • 核心知识点
    • 常见问题分析
    • 课堂练习
    • 课后作业
  • Day09~单点登录系统初步设计及实现
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day10~SSO系统中的登录逻辑基本实现
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课上小技巧
    • 课后作业
  • Day11~SSO系统颁发令牌及资源服务实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业
  • Day12~SSO网关,UI工程,日志记录实践
    • 核心知识点
    • 常见问题分析
    • 常见Bug分析
    • 课后作业

Day01~微服务架构入门

核心知识点

  • 微服务架构诞生的背景(软件即服务,将一个大型软件,拆成若干个小系统;分而治之~北京一个火车站到多个火车站)
  • 微服务架构解决方案(大厂基本自研~自己研发各种组件,中小公司用Spring Cloud Netflix,Alibaba,…)
  • 微服务架构下Maven聚合项目的创建方式?(Maven聚合项目~资源复用:extends,import,简化编译,打包,部署方式)
  • 微服务架构入门聚合项目机构分析及创建?(01-sca,sca-consumer,sca-provider,sca-gateway)

常见问题分析

  • 为什么需要微服务?(对系统分而治,解决因并发访问过大带来的系统复杂性(例如:业务,开发,测试,升级,可靠性等)
  • 微服务设计的特点?(单一职责,独立进程,开发测试效率高,可靠性高,升级难度小,但会带来一定的维护成本)
  • 微服务解决方案有哪些?(大厂自研,中小企业采用开源Spring Cloud Alibaba,Spring Cloud Netfix等 )
  • 微服务设计中需要哪些关键组件(服务的注册,发现,配置,限流降级,访问入口管理,分布式事务管理等)
  • 创建聚合工程的目的?(实现工程之间资源的的共享,简化工程管理)
  • 如何修改聚合工程中项目的编译和运行版本?(pom.xml:build->plugins->plugin->maven-compiler-plugin)
  • maven工程中build元素的作用?(定义项目的编译,打包方式)
  • maven父工程的packaging元素内的值是什么?(父工程默认打包方式为pom方式)
  • maven父工程中dependencyManagement元素的作用是什么?(项目依赖的版本,当前工程或子工程不需要再指定版本)
  • Maven父工程中如何统一定义JDK编译和运行版本?(配置maven编译插件:maven-compiler-plugin)
  • Maven工程pom.xml文件有删除线怎么解决?(修改idea中maven的配置)

常见Bug分析

  • maven配置错误(检查idea中你指定的本地库是否正确)
  • maven依赖无法下载(首先要确保你的依赖的是正确,maven配置是正确,都正确就清idea缓存重启)

课堂练习

  • 删除聚合工程中的子工程模块.
    第一步:在项目结构中删除,例如
    2110-微服务核心知识点及问题分析_第1张图片
    第二步:将项目从idea工作区中删除,例如
    2110-微服务核心知识点及问题分析_第2张图片
    第三步:将项目从父工程的pom文件中删除,例如
    2110-微服务核心知识点及问题分析_第3张图片
  • 移除重建项目module中的pom文件删除线,例如:
    2110-微服务核心知识点及问题分析_第4张图片
  • 构建01-sca的子工程(maven 模块),模块名为sca-ui,其具体业务实现如下:
    第一步:在sca-ui工程的pom.xml文件中添加一个spring-boot-starter-web依赖.
<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
dependencies>

第二步:在sca-ui工程中创建一个springboot启动类,类全名为com.jt.DemoUIApplication.

package com.jt;

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

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

第三步:在sca-ui工程的resources目录下创建一个static目录,并在此目录中创建一个index.html页面
2110-微服务核心知识点及问题分析_第5张图片
第四步:启动sca-ui工程,在浏览器中输入http://localhost:8080/index.html进行测试.
2110-微服务核心知识点及问题分析_第6张图片

课后作业

  • 总结课上知识点(养成好习惯)
  • 检查并设置JDK环境变量JAVA_HOME.
  • 升级MySQL的版本为5.7或以上版本(Mariadb 10.3或以上版本)
  • 预习04-nacos服务注册中心应用实践.

Day02~Nacos注册中心入门

核心知识点

  • 服务注册中心诞生背景? (服务多了,需要统一管理,例如所有公司需要在工商局进行备案)
  • 服务注册中心的选型?(社区活跃度,稳定性,功能,性能,学习成本)
  • Nacos下载,安装(解压),配置(application.properties),启动(startup.cmd),访问(http://ip:port/nacos)
  • 基于Nacos实现服务的注册?(添加依赖,服务配置,启动服务并检查)
  • 基于RestTemplate实现服务的简易调用?(服务消费方调用服务提供方)

常见问题分析

  • 如何理解服务注册中心?(存储服务信息的一个服务)
  • 服务注册中心诞生的背景? (服务多了,需要对服务进行更好管理)
  • 市场上常用的注册中心?(Zookeeper,Eureka,Nacos,Consul)
  • 如何对注册中心进行选型?(社区活跃度,稳定性,功能,性能,学习成本)
  • Nacos 是什么?(是Alibaba公司基于SpringBoot技术实现的一个注册中心,本质上也是一个web服务)
  • Nacos 的基本架构?(Client/Server架构)
  • Nacos 主要提供了什么核心功能?(服务的注册,发现,配置)
  • Nacos 服务启动需要什么前置条件?(配置JDK的JAVA_HOME目录,安装MySQL5.7以上版本,配置连接的数据库)
  • Nacos 服务单机模式,window平台下启动时的指令是什么?(startup.cmd -m standalone)
  • 实现Nacos服务注册需要添加什么依赖?(两个:web,discovery)
  • 实现Nacos服务注册时,必须做哪些配置?(服务名,假如是本机服务注册可以省略服务地址)
  • Nacos如何检查服务状态?(通过心跳包实现,服务启动时会定时向nacos发送心跳包-BeatInfo)
  • 服务之间进行服务调用时,使用了什么API?(RestTemplate,用此对象之前要先创建这个对象并交给spring管理)
  • 服务调用过程是怎样的?
    2110-微服务核心知识点及问题分析_第7张图片

常见Bug分析

  • JAVA_HOME环境变量定义错误,例如:
    在这里插入图片描述
    说明,这里一定要注意JAVA_HOME单词的拼写,JAVA_HOME中定义的JDK是存在的,还有后面的路径不能有分号“;”.

  • MySQL版本比较低(建议mysql5.7或mariadb10.5及以上版本),例如:
    当执行nacos-mysql.sql文件时,出现如下错误:
    在这里插入图片描述

  • sql文件不存在,例如
    在这里插入图片描述

  • SQL文件应用错误,例如:
    在这里插入图片描述

  • Nacos的application.properties配置文件中,连接数据库的配置错误.
    2110-微服务核心知识点及问题分析_第8张图片

  • 数据库的名字配置错误,例如:
    2110-微服务核心知识点及问题分析_第9张图片

  • nacos配置文件application.properties配置错误,例如:
    2110-微服务核心知识点及问题分析_第10张图片

  • 服务启动时,端口被占用了。例如:
    在这里插入图片描述

  • 服务注册时,服务名不正确,格式不正确,配置文件名字不正确,或者没有配置文件,例如:
    在这里插入图片描述

  • 磁盘写权限问题(nacos服务启动时会在当前磁盘目录写日志),例如:
    在这里插入图片描述

  • 基于Nacos实现服务注册失败,例如
    2110-微服务核心知识点及问题分析_第11张图片

  • 客户端500异常,例如
    2110-微服务核心知识点及问题分析_第12张图片

  • 服务调用时,连接异常,例如:
    在这里插入图片描述

  • 客户端404异常,例如:
    在这里插入图片描述

  • 服务调用时底层404问题,例如:
    2110-微服务核心知识点及问题分析_第13张图片

  • 服务访问问题,例如:
    在这里插入图片描述

  • 依赖注入异常,例如:
    在这里插入图片描述

  • 客户端请求方式与服务端不匹配,例如:
    在这里插入图片描述

  • 依赖版本问题,例如:
    在这里插入图片描述

  • 服务配置读取问题,例如:
    在这里插入图片描述

课后作业

  • 总结课堂知识点
  • 完成基于nacos的服务注册
  • 完成基于RestTemplate对象实现服务调用。
  • 预习04-nacos中的负载均衡设计及实现.
  • 尝试实现基于idea启动nacos,自己查询然后进行实践.
    在这里插入图片描述
  • 尝试实现基于idea连接指定数据库,例如:
    第一步:打开DataSource,找到mysql,例如:
    在这里插入图片描述
    第二步:配置连接的数据库,例如:
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Day03~远程服务调用实践

核心知识点

  • 远程过程调用背景分析?(RPC,多个服务协同作战)
  • 负载均衡背景分析及解决方案?(提高系统的并发处理能力)
  • LoadBalancerClient对象的作用以及应用。
  • @Loadbalanced注解的作用以及应用。
  • Feign 诞生的背景,应用方式,常见问题以及原理。

常见问题分析

  • 为什么要负载均衡?(提高系统的并发处理能力,双管齐下,类似银行的各个营业点)
  • LoadBalancerClient对象的作用是什么?(基于负载均衡算法从注册中心获取服务实例)
  • @LoadBalanced注解作用?(描述RestTemplate对象,让系统底层为RestTemplate对象赋能,对请求过程进行拦截)
  • Ribbon是什么,基于Ribbon可以解决什么问题?(一个负载均衡组件,这个组件中提供一套负载均衡算法)
  • 你了解哪些负载均衡策略?(基于IRule接口去查看,快捷键ctrl+h)
  • 我们如何修改负载均衡策略?(配置文件->例如application.yml,配置类->例如启功类)
  • 为什么使用Feign方式的服务调用?(声明式远程调用,优化结构,简化服务调用过程代码的编写)
  • 如何基于feign方式实现远程服务调用?(依赖-openfeign,配置,feign接口定义)
  • @EnableFeignCleints 注解的作用是什么?(描述配置类,例如启动类,告诉底层启动feign starter组件)
  • @FeignClient注解的作用是什么?(告诉Feign Starter,在项目启动时,为此注解描述的接口创建实现类-代理类)
  • 如何理解基于Feign方式的远程服务调用?(底层封装了服务调用过程,明修栈道暗度陈仓)
  • Feign方式如何实现负载均衡?(底层基于ribbon组件实现)
  • Feign接口指向的对象是谁?(代理对象-feign接口的实现类对象)
    在这里插入图片描述
  • 常用服务发现、服务调用方式有哪些?
    在这里插入图片描述* 这部分内容中你接触到了哪些设计模式呢?(单例,享元,代理,工厂,模板方法,策略,观察者,…)

常见Bug分析

  • SocketTimeoutException,例如:
    在这里插入图片描述

  • NullPointerException,例如:
    在这里插入图片描述
    在这里插入图片描述

  • 负载均衡类的配置问题,例如:
    在这里插入图片描述

  • 端口被占用,例如
    在这里插入图片描述

  • UnknownHostException,例如
    在这里插入图片描述
    在这里插入图片描述

  • Fien接口对象依赖注入异常,例如:
    在这里插入图片描述

  • 数据读取超时,例如:
    在这里插入图片描述

  • 服务访问时的404异常,例如:
    在这里插入图片描述

  • Feign接口方法中@PathVariable注解参数定义问题,例如:
    在这里插入图片描述

  • 读数据超时,例如:
    在这里插入图片描述

  • 依赖注入异常,例如:
    在这里插入图片描述

课后作业

  • 完成课上知识点总结。
  • 实践基于RestTemplate和Feign方式的服务调用。
  • 预习05-Nacos配置中心应用实践。
  • 尝试完成Idea中Http Client 工具的应用?(基于此工具进行restful风格的请求测试)
    在这里插入图片描述
    在这里插入图片描述
  • 修改sca-consumer端默认的负载均衡策略?(自己查资料实现)

方案1:修改sca-consumer配置文件(application.yml),添加如下语句,例如:

sca-provider: #这个是要进行远程调用的服务id(服务名)
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #负载均衡算法

对于方案1写法,在写的过程没有提示,编写困难,但是将来的可运维性会比较好,我们这部分配置写到配置中心,不需要重启服务即可实现配置的动态发布,动态更新。

方案2:修改sca-consumer的启动类,在启动类中添加如下方法,例如:

@Bean
public IRule ribbonRule() {
    return new RandomRule();
}

对于方案2的写法,编写相对简单,编写过程都有提示,但是将来的可运维性比较差,项目打包以后,我们无法再修改负载均衡算法。

Day04~Nacos配置中心应用实践

核心知识点

  • 配置中心诞生背景。
  • 市场上主流的配置中心。
  • Nacos配置中心简介。
  • Nacos配置中心入门实践。
  • Nacos配置中心的配置管理模型。

常见问题分析

  • 什么是配置中心?(存储项目配置信息的一个服务,这个服务可以实现配置的动态发布和更新)
  • 为什么要使用配置中心?(集中管理配置信息,动态发布配置信息,服务自动感知配置)
  • 市场上有哪些主流的配置中心?(Apollo,nacos,……)
  • 配置中心一般都会配置什么内容?(可能会经常变化的配置信息,例如连接池,日志、线程池、限流熔断规则)
  • 什么信息一般不会写到配置中心?(服务端口,服务名,服务的注册地址,配置中心地址)
  • 项目中为什么要定义bootstrap.yml文件?(此文件被读取的优先级比较高,可以在服务启动时读取配置中心的数据)
  • Nacos配置中心宕机了,我们的服务还可以读取到配置信息吗?(可以从服务的本地内存读取)
  • 微服务应用中客户端如何感知配置中心数据变化?(1.4.x版本的nacos客户端会基于长轮询机制从nacos获取配置信息)
  • 服务启动后没有从配置中心获取我们的配置数据是什么原因?(依赖,bootstrap.yml,配置单词,格式,配置模型)
  • 你项目中使用的日志规范是什么?(SLF4J~门面模式)
  • 你了解项目中的日志级别吗?(debug,info,warn,error可以基于日志级别控制日志的输出)
  • Nacos配置管理模型的背景?(环境不同配置不同)
  • Nacos配置中的管理模型是怎样的?(namespace>group>service/data-id)
  • Nacos客户端(微服务)是否可以读取共享配置?(可以)

常见Bug分析

  • mysql中没有配置中心数据,例如:
    在这里插入图片描述
  • 包导入错误,例如:
    在这里插入图片描述
  • 配置中心配置格式不正确,例如:
    在这里插入图片描述
  • 程序中服务读取配置时,找不到配置,例如:
    在这里插入图片描述

课后作业

  • 总结课上知识点
  • 完成文档中的共享配置应用.
  • 预习06-sentinel限流熔断操作实践。
  • 尝试设计并完成一个本地cache的应用(拓展-CopyOnWriteArrayList)。

在ProviderCacheController,进行本地缓存设计应用,例如:

private CopyOnWriteArrayList<String> cache=new CopyOnWriteArrayList<>();
@GetMapping("/provider/cache02")
public  List<String> doUseLocalCache02(){
    if(!useLocalCache){//假如useLocalCache的值为false,表示不开启本地cache.
       log.info("select data from database");
       return Arrays.asList("A","B","C");//假设这些数据来自数据库
    }
    if(cache.isEmpty()){
      synchronized (this) {
         if (cache.isEmpty()) {
            //模拟从数据库获取数据
            log.info("select data from database");
            List<String> data = Arrays.asList("A", "B", "C");
            //将数据放入cache中
            cache.addAll(data);
         }
      }
    }
    log.info("select data from cache");
    return cache;
}

Day05-Sentinel 限流应用实践

核心知识点

  • 服务限流、降级的背景(服务的治理)
  • Sentinel限流入门实践(控制台8180-定义规则,客户端服务应用规则:依赖,配置)
  • Sentinel常用限流模式(直接->当前url,关联->保证核心业务,链路->红绿灯)
  • @SentinelResource注解作用及限流异常处理(AOP设计)
  • Sentinel默认异常限流处理类(DefaultBlockExceptionHandler)

常见问题分析

  • 为什么要进行限流、降级? (系统处理能力有限,可以通过限流方式,保证系统可靠运行,以退为进)
  • 你了解Sentinel限流有哪些算法? (计数器,令牌桶,漏桶,滑动窗口算法~sentinel默认)
  • Sentinel常用限流模式?(直接,关联->保证核心业务,链路->红绿灯)
  • @SentinelResource注解的作用,你用过哪些属性?(在链路限流中描述资源节点,切入点方法)
  • Sentinel常用限流效果有哪些?(快速失败,预热,排队)
  • Sentinel中限流被触发时出现的异常类型是什么?(都是BlockException类型的子类)
  • 如何对限流结果进行处理?(有默认处理方案-DefaultBlockExceptionHandler,也可以自定义.)
  • Sentinel限流的基本原理?(底层对服务请求进行拦截,然后通过流控规则限定对资源访问)
    在这里插入图片描述

常见Bug分析

  • sentinel 服务启动不起来?(要配置jdk环境变量path,要使用JDK8版本)
  • sentinel 面板不显示我们的服务?(依赖,配置>一定要注意缩进,先访问,放大招-清idea缓存重启)
  • 配置完sentinel后,业务服务启动不了了?(大部分都是配置错了)

课后作业

  • 总结课上知识点.
  • 了解常用限流算法.
  • 预习并尝试完成Sentinel服务降级,热点规则设计,系统规则设置,授权规则设置.
  • 预习07~spring cloud gateway网关。
  • 基于spring mvc 拦截器对系统中指定资源进行时间访问限制?
    第一步:拦截器原理分析(回顾spring mvc中的拦截器),例如:
    在这里插入图片描述
    第二步:自定义拦截器,例如:
package com.jt.provider.interceptor;
public class TimeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
    throws Exception {
        System.out.println("==preHandle==");
        //1.获取当前时间
        LocalTime now = LocalTime.now();//LocalTime为jdk8中的一个获取当前时间的api
        //2.获取当前的小时并进行逻辑判断
        int hour = now.getHour();//8:10~8
        System.out.println("hour="+hour);
        if(hour<9||hour>18){
            throw new RuntimeException("请在9~18时间范围内访问");//return false
        }
        return true;//false请求到此结束,true表示放行,会去执行后续的拦截器或controller对象
    }
}

第三步:配置拦截器,例如:

package com.jt;
@Configuration
public class SpringWebConfig implements WebMvcConfigurer {
    /**
     * 注册拦截器(添加到spring容器),并指定拦截规则
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TimeInterceptor())
                .addPathPatterns("/provider/sentinel01");
    }
}

第四步:打开浏览器,对/provider/sentinel01路径进行访问,对访问结果进行访问。

Day06-Sentinel 进阶应用实践

核心知识点

  • Sentinel降级(熔断)入门实现(出现不稳当的系统服务时,暂停对此服务的访问)
  • Sentinel实现热点参数限流(热点视频,文章,…)
  • Sentinel系统规则配置(例如cpu使用率,QPS,…),
  • Sentinel授权规则配置(黑白名单,黑白设计由业务决定)

常见问题分析

  • 如何理解熔断?(可以理解为暂时关闭不稳定的服务,要学会舍得)
  • 如何自定义熔断异常处理规则?(实现BlockExceptionHandler接口)
  • 如何理解热点参数?(频繁访问的数据,系统底层如何判定哪些数据是频繁访问-lru)
  • 系统规则是全局规则吗,常见规则有哪些? (是,响应时间-RT,QPS,CPU,线程数)
  • 授权规则需要我们自己写请求解析类吗?(需要,实现RequestOriginParser接口)

常见Bug分析

  • 请求参数单词错误。

课后作业

  • 总结课上知识点。
  • 了解Lru算法解决了什么问题?
  • 总结几个Sentinel中用到设计模式?
  • 预习API网关Gateway限流实现(07-网关应用实践)。

Day07-Gateway 应用实践

核心知识点

  • API 网关(Gateway)诞生背景
  • 市场主流微服务网关(Spring Cloud Gateway,zuul,…)
  • API Gateway实现服务的保护和转发(重点)
  • API Gateway层面的负载均衡实现(重点,lb://sca-provider)
  • API Gateway请求处理原理分析(重点:官方图,了解关键代码,执行过程)
  • API Gateway中常用谓词(predicate)对象及实践。

常见问题分析

  • 为什么要使用api网关?(服务保护,统一url访问,统一身份认证,统一跨域设计,。。。)
  • 网关入门实践的步骤? (依赖,配置,启动,服务访问)
  • 网关项目中的负载均衡是如何实现?(底层基于Ribbon实现,可以在RibbonLoadBalancerClient中加断点分析)
  • 说说SpringCloud gateway处理请求的基本流程?(官方,断点)
  • 网关中的谓词对象类型?(GatewayPredicate)
  • 网关中的谓词对象是如何创建的?(谓词工厂)
  • 你在网关中配置过哪些常用谓词?(Path,Method,Before,Query,Header,…)

常见BUG分析

  • 配置文件格式不正确,例如
    在这里插入图片描述
  • 服务访问被拒绝,例如
    在这里插入图片描述
  • 服务注册失败(nacos没启动),例如:
    在这里插入图片描述
  • 503 异常(找不到可用的服务)
    在这里插入图片描述

课后作业

  • 总结课上知识点
  • 练习基于Gateway实现负载均衡方式的配置。
  • 练习常用谓词(Predicate)应用。
  • 预习并尝试完成网关中的过滤器以及sentinel限流设计。

Day08-Gateway 应用进阶实践

核心知识点

  • API Gateway中过滤器(Filter)的类型及实践。
  • API Gateway中基于sentinel实现服务限流(API,路由id)。
  • API Gateway中基于自定义限流结果的处理(GatewayCallbackManager)。

常见问题分析

  • 网关中的过滤器是如何分类的?(GlobalFilter,GatewayFilter:需要手动配置)
  • 我们是否可以自定义谓词,过滤器对象?(可以,参考官方默认的定义)
  • 网关层面如何基于sentinel实现限流?(有关sentinel的两个依赖,配置,JVM参数)
  • 网关层面的限流类型有哪些?(路由id,API分组)
  • 我们是否可以对限流结果进行自定义处理?(可以)

课堂练习

  • 网关中设置黑白名单?
    第一步:在配置文件添加如下配置,例如:
web:
  request: # 注意假如属性名是两个单词,要用"-"进行连接,例如black-urls
     black-urls: # 系统底层解析这部分时,会自动以"-"作为分隔符,将内容存储到list集合
       - /nacos/provider/echo/a
       - /nacos/provider/echo/b

第二步:在项目中添加一个全局过滤器,例如:

package com.jt.filter;
import org.apache.http.HttpHeaders;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * 基于此全局过滤器对请求url进行黑白名单识别
 * @ConfigurationProperties 注解描述类时,用于告诉系统底层
 * 要从配置文件中读取指定配置信息(prefix属性用于指定读取哪部分
 * 前缀对应的信息)
 */
@ConfigurationProperties(prefix = "web.request")
@Component
public class BlackUrlGlobalFilter implements GlobalFilter, Ordered {//Authentication(认证)
    private List<String> blackUrls=new ArrayList<>();
    /**
     * 当系统底层读取@ConfigurationProperties(prefix = "web.request")
     * 注解中描述的内容时,会自动基于名字调用此set方法
     */
    public void setBlackUrls(List<String> blacks) {
        this.blackUrls = blacks;
    }
    /**
     * 此方法为一个处理请求的方法
     * @param exchange 基于此对象获取请求和响应
     * @param chain 过滤链对象
     * @return SpringWebFlux中的Mono对象(一个Publisher对象),
     * 是springframework5.0后推出的新特性,
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange,
                             GatewayFilterChain chain) {
        //1.获取请求和响应对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //2.获取请求url
        String urlPath=request.getURI().getPath();//nacos/provider/echo/gateway
        System.out.println("blackPath="+blackUrls);
        System.out.println("urlPath="+urlPath);
        //3.对请求url进行黑白名单分析
        //黑名单则请求到此结束
        if(blackUrls.contains(urlPath)){
            //设置响应状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);//401
            //设置请求头中响应数据内容类型
            response.getHeaders()
                    .add(HttpHeaders.CONTENT_TYPE,"text/html;charset=utf-8");
            //构建一个数据buffer对象
            DataBuffer dataBuffer=
                    response.bufferFactory()
                            .wrap("请求url是黑名单".getBytes());
            //将数据封装到Mono对象
            return response.writeWith(Mono.just(dataBuffer));
        }
        //白名单则放行(执行下一步,假如有下个过滤器,就执行下一个过滤器)
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -1;
    }
}
  • 自定网关层面的限流异常处理对象?
package com.jt.callback;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.fastjson.JSON;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

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

@Component
public class GatewayRequestBlockHandler implements BlockRequestHandler {
    @Override
    public Mono<ServerResponse> handleRequest(
            ServerWebExchange serverWebExchange,
            Throwable throwable) {
        Map<String,Object> map=new HashMap<>();
        map.put("state",429);
        map.put("message","two many request");
        String jsonStr= JSON.toJSONString(map);
//        return ServerResponse.ok()
//                .body(Mono.just(jsonStr), String.class);
        return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                .contentType(MediaType.TEXT_PLAIN)
                .body(Mono.just(jsonStr), String.class);
    }
}

课后作业

  • 总结课上知识点
  • 完成黑白单全局过滤器的设计
  • 完成网关层面基于路由ID和API分组方式的限流
  • 完成网关层面自定义限流异常的处理.
  • 微服务架构下ajax请求响应处理实践。

第一步:业务描述(通过sca-ui工程向网关工程发送ajax请求,并进行响应处理)
在这里插入图片描述
第二步:创建sca-ui工程的html页面,然后通过触发按钮发送ajax请求,例如


DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
  <div>
    <h2>The Index Pageh2>
    <button onclick="doBuy()">Buybutton>
    <span id="result">span>
  div>
  <script src="https://unpkg.com/axios/dist/axios.min.js">script>
  <script>
     //前端如何排错(日志,debugger,排除)
     function doBuy(){
         console.log("==doBuy==");
        //1.基于axios框架发送异步ajax请求
         let url="http://localhost:9000/nacos/provider/echo/1"
         let span=document.getElementById("result");
         axios.get(url)

             .then(function (response) {//请求ok,执行then
                 console.log(response.data);
                 //2.将响应结果更新到页面上
                 span.innerHTML = response.data
             })
             .catch(function (error) {
                 debugger //设置断点
                 //console.log(error);
                 if(error.response.status==429){
                     span.innerHTML = error.response.statusText;
                 }
             });

     }
 script>
body>
html>

第三步:在sca-gateway的配置文件或配置中心中添加跨域配置,例如:

spring:
  cloud:
    gateway: 
      globalcors: #跨域配置
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods: "*"

第五步:按项目架构设计启动服务,进行测试。

http://localhost:8080/index.html
  • 将路由配置写到配置中心进行实践?(自己动手丰衣足食)

第一步:在sca-gateway项目中添加配置依赖,例如:

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>

第二步:修改application.yml配置文件名称为bootstrap.yml,并添加配置中心配置。

spring:
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
        file-extension: yml

第三步:在nacos的public命名空间中创建sca-gateway.yml配置,内容如下:
在这里插入图片描述
说明,此配置添加后,可以将bootstrap.yml中网关部分的配置注释掉。

第四步:启动nacos,sentinel,provider,gateway服务,然后进行访问测试。

Day09~单点登录系统初步设计及实现

核心知识点

  • 单点登录系统诞生的背景。
  • Java中单点登录系统解决方案。
  • 单点登录系统(SSO)中的服务划分及关系设计。
  • 单点登录系统中父工程的创建及初始化。
  • 系统基础服务(sso-system)工程的创建及初始化
  • 系统基础服务(sso-system)工程中pojo对象设计及实现

常见问题分析

  • 为什么要做单点登录设计?(业务简化,代码复用,不需要每个服务都登录一次)

  • 你知道哪些SSO系统解决方案?(基于用户登录状态信息的存储进行方案设计)

  • 单点登录系统中你的服务是如何设计的,工程结构是怎样的?

  • 项目中使用的连接池什么?(HikariCP)

  • Java中连接池设计需要遵循的数据源规范是谁?(javax.sql.DataSource)

  • 连接池这块你能想到的设计模式有哪些?(单例,享元,桥接,slf4j门面)

  • 如何排除springboot工程中junit4依赖?
    2110-微服务核心知识点及问题分析_第14张图片

  • SpringBoot工程中如何基于junit4的单元测试?
    2110-微服务核心知识点及问题分析_第15张图片

  • SpringBoot工程中如何基于Junit5进行单元测试?

2110-微服务核心知识点及问题分析_第16张图片

  • SpringBoot单元测试类应该写在哪个位置?
    2110-微服务核心知识点及问题分析_第17张图片

  • 基于idea的为类自动生成序列化id?
    第一步:修改idea中的配置。
    在这里插入图片描述
    第二步:在User类上按alt+enter,例如:
    在这里插入图片描述

  • @Autowired注解描述的Mapper对象有红色波浪线,但运行没有错误,如何去除红色波浪线。
    在这里插入图片描述

常见Bug分析

  • MySql指令不可用,例如:
    在这里插入图片描述

  • 单元测试类位置写错了,例如:
    2110-微服务核心知识点及问题分析_第18张图片

  • 单元测试类定义的位置不正确,例如
    2110-微服务核心知识点及问题分析_第19张图片

  • Springboot工程中中存在多个启动类,例如

2110-微服务核心知识点及问题分析_第20张图片

  • DataSource包导入错误,例如:

2110-微服务核心知识点及问题分析_第21张图片

  • 单元测试方法不能有参数,例如:

2110-微服务核心知识点及问题分析_第22张图片

  • 单元测试方法的返回值类型只能是void,例如:

2110-微服务核心知识点及问题分析_第23张图片

  • Junit4单元测试方法,其访问修饰符必须为public,例如

2110-微服务核心知识点及问题分析_第24张图片

  • 连接数据库的url中时区定义有问题,例如:
    在这里插入图片描述
  • NullPointerExeption 异常分析?
    在这里插入图片描述
  • 数据库依赖问题,例如:
    在这里插入图片描述

课后作业

  • 总结课上内容
  • 完成单点登录系统中的基础服务的设计和实现

Day10~SSO系统中的登录逻辑基本实现

核心知识点

  • 系统服务中(sso-system)中定义数据访问逻辑对象(UserMapper)
  • 系统服务中(sso-system)中定义业务逻辑接口及实现类对象(UserService,UserServiceImpl)
  • 系统服务中(sso-system)中定义控制逻辑对象(UserController)
  • 创建认证服务(sso-auth)并进行初始化(添加依赖,定义配置,编写启动类,执行默认登录)
  • 认证服务(sso-auth)中创建User对象用于封装从远程system服务中获取的用户信息
  • 认证服务中定义远程访问Feign接口(RemoteUserService~基于此接口调用sso-system服务中的用户信息)
  • 基于Security规范定义用户业务逻辑服务对象(UserDetailsServiceImpl~调用RemoteUserService获取和封装用户信息)
  • 定义用户认证基本配置类(SecurityConfig~配置密码加密对象,提供认证管理器对象)
  • 实现自定义登录逻辑测试(校验登录正确账号和错误账户下服务端的响应结果)
  • 熟悉SpringSecurity的认证流程?(Client->Filters->AuthenticationManager–>UserDetailService->…)

常见问题分析

  • UserMapper接口如何交给Spring管理(@Mapper,@MapperScan)
  • 用户业务逻辑对象中你是如何开启事务的?(@Transactional)
  • @Transactional中的readOnly属性默认值是什么?(false,这个值一般应用在非只读事务上)
  • 用户业务逻辑对象中如何开启本地缓存?(@EnableCaching用于开启缓存,@Cacheable用于定义切入点方法)
  • 系统服务(system)工程中事务开启,缓存应用都是基于什么设计思想实现的?(AOP)
  • SpringBoot工程中默认的AOP代理对象是基于什么方式创建的?(CGLIB)
  • 为什么定义RemoteUserService 接口(Feign)?(基于此接口调用远程sso-system服务)
  • sso-auth服务中用户业务数据的获取在哪里?(客户端提交的用户名,sso-system服务提供的数据库数据)
  • 为什么要构建SecurityConfig对象?(配置加密算法,提供认证管理器对象)
  • 为什么要让SecurityConfig类要继承WebSecurityConfigurerAdapter类型?(重写默认的认证规则)
  • 认证过程中使用的密码加密对象是谁?(BCryptPasswordEncoder,不可逆加密对象)
  • 用户登录时,需要从数据库查询哪些信息?(用户信息以及用户的权限信息)
  • 如何基于用户id查询用户权限,你有什么方案?(3种)
    在这里插入图片描述
  • 单体架构中的用户的状态的存储是如何实现的?(了解,默认是存储到了tomcat的session对象中)
    在这里插入图片描述

常见Bug分析

  • 没有PasswordEncoder对象,例如:
    在这里插入图片描述

  • 远程调用服务404异常,例如:
    在这里插入图片描述

  • 远程调用服务没启动或服务名不正确,例如
    在这里插入图片描述

  • 服务名的定义和使用不规范,例如:
    在这里插入图片描述

  • Feign接口依赖注入异常,例如:

在这里插入图片描述

  • NullPointerException,例如

在这里插入图片描述

课上小技巧

  • Maven Helper 插件安装及应用,例如
    在这里插入图片描述
    在这里插入图片描述

课后作业

  • 总结课上知识点
  • 预习并尝试完成统一认证服务中TokenConfig,Oauth2Config类的定义
  • 预习并尝试完成资源服务工程(sso-resource)设计?

Day11~SSO系统颁发令牌及资源服务实践

核心知识点

  • 认证服务器(sso-auth)中Token设计(UUID令牌,JWT令牌)
  • 认证服务器(sso-auth)中Oauth2规范基本配置(认证入口,为谁认证,由谁认证,认证后颁发什么令牌)
  • 基于Postman进行认证测试?(请求方式,请求url,认证参数)
  • 资源服务器(sso-resource)核心业务分析及认证,授权规则设计及实现(匿名,认证,授权)

常见问题分析

  • JWT是什么?(是JSON WEB TOKEN这几个单词的缩写,描述的是web应用的一种令牌格式)
  • JWT有几部分构成?(头:令牌类型,签名算法,负载:允许包含用户登录状态 ,签名:防止令牌被篡改)
  • 为什么要采用JWT令牌?(可以存储用户登录状态信息,避免访问资源时从数据库查询认证信息)
  • 基于Oauth2协议的认证服务器默认的令牌生成策略是什么?(UUID.randomUUID())
  • 认证服务器中常见令牌相关设计存储方案有哪些?(Mysql,Redis,Jwt)
  • 认证服务器对用户进行认证时,客户端提交了哪些关键信息?(username,password,client_id,grant_type,client_secret)
  • 认证服务器完成认证操作后,服务端返回哪些信息?(访问令牌,刷新令牌,令牌类型,作用域,编号)
  • 认证服务器中完成认证业务的关键对象有哪些?(Filter,AutenticationManager,UserDetailService,.)
  • 资源服务器如何设计的认证,授权规则?(三个维度:匿名,登录,授权)
  • 访问令牌与刷新令牌有什么不一样?(客户端是要携带访问令牌访问资源的,刷新令牌是为了再次生成访问令牌)
  • 访问令牌,刷新令牌有有效时长吗?(刷新令牌有效时长一般要大于访问令牌有效时长)

常见Bug分析

  • 客户端传参不匹配,例如:
    在这里插入图片描述

  • AuthenticationManager对象没有配置(SecurityConfig),例如:
    在这里插入图片描述

  • 响应的令牌不正确,例如:

在这里插入图片描述

  • 400异常,例如

在这里插入图片描述

  • 请求方式不正确,例如
    在这里插入图片描述
  • 访问地址错误,例如:
    在这里插入图片描述

课后作业

  • 总结课上知识点及常见问题
  • 完成单点登录系统的认证服务器以及资源服务器的设计和实现
  • 完成微服务文档中网关工程,UI工程的设计和实现.
  • 尝试完成09-SSO微服务工程中用户行为日志的记录.

Day12~SSO网关,UI工程,日志记录实践

核心知识点

  • SSO系统中网关服务器(sso-gateway)实现路由转发,跨域设计,负载均衡,限流。
  • SSO系统中UI工程中页面设计(Bootstrap+VUE+axios)及请求响应代码分析(200,401,403)。
  • SSO系统中用户访问资源时,获取并记录用户行为到数据库?

常见问题分析

  • 网关服务器在哪里做了负载均衡(lb://)?
  • 为什么网关层面要做跨域设计?(Ajax技术不支持跨域请求,将所有服务的跨域共性提取到网关层面)
  • UI工程中用户端如何提交ajax请求的?(axios,底层ajax对象为XMLHttpRequest)
  • System工程中如何记录用户行为日志的?(通过异步方式将日志写到数据库,@EnableAsync,@Async)
  • 系统工程中的用户行为日志来自哪里?(资源服务器,此服务器记录用户访问资源的一些信息)
  • 资源服务器通过什么样的方式获取用户行为信息?(AOP)
  • 如何在非@Controller对象(例如切面,工具类)中获取请求对象?(RequestContextHolder)
  • 如何在资源服务器中获取登录用户对象?(借助SecurityContextHolder对象)
  • 我们如何通过连接点对象(JoinPoint)获取的方法签名(MethodSignature)?
  • 我们在资源工程中如何应用Feign组件的?(添加依赖,定义远程日志服务接口,启动类开启feign应用)
  • Feign是基于什么方式进行远程服务调用的?(声明式-声明要调用服务以及url资源-restful 风格,)

常见Bug分析

  • 400异常,请求参数不合法(参数个数,类型,格式)。

  • 401异常,认证失败?(提交的数据不正确)

  • 403异常,没有资源访问权限?(说明用户为已认证用户,但是没有资源的访问权限)

  • 415异常,数据协议有问题?(比方说,你要json数据,但是数据格式定义的是text)

  • 调用的服务没有启动,例如:
    在这里插入图片描述

  • 503异常,例如
    在这里插入图片描述

课后作业

  • 总结课上知识点
  • 完成用户行为日志的记录实现。

你可能感兴趣的:(微服务,maven,java)