2107-微服务课上问题分析及总结

最后

权威指南-第一本Docker书

引领完成Docker的安装、部署、管理和扩展,让其经历从测试到生产的整个开发生命周期,深入了解Docker适用于什么场景。并且这本Docker的学习权威指南介绍了其组件的基础知识,然后用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。

总共包含了:简介、安装Docker、Docker入门、使用Docker镜像和仓库、在测试中使用Docker、使用Docker构建服务、使用Fig编配Docke、使用Docker API、获得帮助和对Docker进行改进等9个章节的知识。

image

image

image

image

关于阿里内部都在强烈推荐使用的“K8S+Docker学习指南”—《深入浅出Kubernetes:理论+实战》、《权威指南-第一本Docker书》,看完之后两个字形容,爱了爱了!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

在这里插入图片描述

  • sca-provider 工程引入sca-common工程依赖

com.jt

sca-common

1.0-SNAPSHOT

  • sca-provider工程中使用sca-common工程公共类StringUtils.java

第一步:在sca-common工程中创建StringUtil.java工具类,例如:

package com.jt.common.util;

/**

  • 自己定义一个操作字符串的工具类

*/

public class StringUtils {

/**

  • 判断字符串的值是否为空

  • @param str 这个参数就是你要验证的字符串

  • @return true表示空

*/

public static boolean isEmpty(String str){

return str==null||“”.equals(str);

}

}

第二步:在sca-provider工程中添加spring-boot-start依赖,例如:

org.springframework.boot

spring-boot-starter

第三步:在sca-provider工程中的test目录下定义单元测试类,并进行测试,例如:

package com.example;

import com.jt.common.util.StringUtils;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.SpringBootConfiguration;

import org.springframework.boot.test.context.SpringBootTest;

/**

  • @SpringBootTest 注解描述的类为Spring工程的单元测试类

*/

@SpringBootConfiguration //(假如工程中有启动类,注解就不需要加了)

@SpringBootTest

public class StringTests {

/**

  • 在当前测试类方法中,使用了sca-common项目中的StringUtils工具类

*/

@Test

void testStringEmpty(){

String content=“helloworld”;

boolean flag= StringUtils.isEmpty(content);

System.out.println(flag);

}

}

  • 检查自己电脑的JAVA_HOME环境变量?

方式1:打开电脑的命令行窗口,输入set JAVA_HOME 指令,例如:

在这里插入图片描述

方式2:假如是window平台还可以通过,如下方式进行检查,例如:

在这里插入图片描述

  • 检查自己电脑环境中的JVM虚拟机是否为64位的,例如:

在这里插入图片描述

  • 登录mysq,检查mysql或maridb的版本,例如:

在这里插入图片描述

Day02~Nacos 注册中心入门

============================================================================

核心知识点


  • 注册中心诞生的背景? (所有公司需要在工商局进行备案)

  • 注册中心的选型?(社区活跃度,稳定性,功能,性能,学习成本)

  • Nacos下载,安装,配置,启动,访问(http://ip:port/nacos)

  • 服务向Nacos的注册?(添加依赖,服务配置,启动服务并检查)

  • Nacos进行服务监控的方式?(心跳包)

  • 服务(进程)之间的调用?(借助RestTemplate.思考Spring中的JdbcTemplate,SqlSessionTemplate等对象的作用)

常见问题分析


  • 注册中心诞生的背景? (服务多了,需要对服务进行更好管理)

  • 市场上常用的注册中心?(Zookeeper,Eureka,Nacos,Consul)

  • 如何对注册中心进行选型?(社区活跃度,稳定性,功能,性能,学习成本)

  • Nacos 是什么?(是Alibaba公司基于SpringBoo技术t实现的一个注册中心,本质上也是一个服务)

  • Nacos 的基本架构?(Client/Server架构)

  • Nacos 主要提供了什么核心功能?(服务的注册,发现,配置)

  • Nacos 服务启动需要什么前置条件?(配置JDK的JAVA_HOME目录,安装MySQL5.7以上版本,配置连接的数据库)

  • Nacos 服务单机模式,window平台下启动时的指令是什么?(startup.cmd -m standalone)

  • 实现Nacos服务注册需要添加什么依赖?(两个)

  • 实现Nacos服务注册时,必须做哪些配置?(服务名,假如是本机服务注册可以省略服务地址)

  • Nacos如何检查服务状态?(通过心跳包实现)

  • 服务之间进行服务调用时,使用了什么API?(RestTemplate)

常见Bug分析


  • JAVA_HOME环境变量定义错误,例如:

在这里插入图片描述

说明,这里一定要注意JAVA_HOME单词的拼写,JAVA_HOME中定义的JDK是存在的.

  • MySQL版本比较低,例如:

当执行nacos-mysql.sql文件时,出现如下错误:

在这里插入图片描述

  • SQL文件应用错误,例如:

在这里插入图片描述

  • Nacos的application.properties配置文件中,连接数据库的配置错误.

在这里插入图片描述

  • 服务注册时,服务名不正确,例如:

在这里插入图片描述

  • Nacos 服务注册失败,例如

加粗样式

  • 客户端500异常,例如

在这里插入图片描述

  • 服务调用时,连接异常,例如:

在这里插入图片描述

  • 服务调用时底层404问题,例如:

在这里插入图片描述

课后作业


  • 重新创建新的聚合项目(例如10-sca)

  • 重新实现服务的注册和调用(ca-consumer调用ca-provider)

  • 尝试完成负载均衡方式的服务调用(参考博客文档)

Day03~服务发现及调用

=======================================================================

核心知识点


  • 基于LoadBalancerClient 实现服务发现和负载均衡

  • @Loadbalanced注解的作用以及应用分析

  • Feign方式的服务调用实践

常见问题分析


  • 何为服务发现?(从nacos获取服务实例)

  • LoadBalancerClient的作用?(从nacos获取服务实例列表,然后本地基于负载均衡算法获取服务实例)

  • @Loadbalanced作用?(描述RestTemplate对象,让系统底层为RestTemplate对象赋能)

  • Feign是什么?(Spring Cloud微服务规范中的一组远程调用API)

  • 为什么使用Feign?(优化服务调用结构)

  • 如何使用Feign实现服务调用?(依赖,@EnableFeignClients,@FeignClient)

  • Feign方式的服务调用原理是怎样的?(底层基于代理对象实现)

常见Bug分析


  • 服务启动时端口被占用,例如:

在这里插入图片描述

  • RestTemplate对象应用错误,例如:

在这里插入图片描述

  • @Autowired描述的属性有红色下划波浪线,例如:

在这里插入图片描述

  • 依赖注入(DI)问题,例如

在这里插入图片描述

  • 服务名应用问题,例如:

在这里插入图片描述

  • Feign 接口方法中@PathVariable注解应用问题.

在这里插入图片描述

课后作业


  • 总结微服务中的服务发现及调用方式.

  • 构建一个简易的Browser/Tomcat对象,实现两个对象的网络通讯(了解).

  • 预习@FeignClient中fallbackFactory注解的应用.

  • 预习Nacos配置中心.

作业答案


  • 服务调用方式总结,例如:

在这里插入图片描述

  • 简易Browser/Tomcat对象实现?(Java中的网络通讯需要借助Socket/ServerSocket对象)

第一步:构建Tomcat对象,例如:

package com.jt.common.net;

import java.io.IOException;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

/**

  • 模拟一个简易的tomcat(服务)

  • 基于Java中的网络编程实现(java.net)

  • 1)网络服务端(ServerSocket)

  • 2)网络客户端(Socket)

*/

public class Tomcat {//企业规范

public static void main(String[] args) throws IOException {

//1.创建服务(例如:启动nacos,启动…),并在9999端口进行监听

//网络中计算机的唯一标识是什么?ip

//计算机中应用程序的唯一标识是什么?port

ServerSocket server=new ServerSocket(9999);

System.out.println(“server start …”);

//2.启动服务监听

while(true){

//监听客户端的链接(这里的socket代码客户端对象)

Socket socket=server.accept();//阻塞方法

//在这里可以将socket对象的信息记录一下.(服务注册)

//创建输出流对象,向客户端输出hello client

OutputStream out =

socket.getOutputStream();

//byte[] responseContent=“hello client”.getBytes();

byte[] responseContent=(“HTTP/1.1 200 ok \r\n” +

“Content-Type: text/html;charset=utf-8 \r\n” +

“\r\n” +

hello client

”).getBytes();

out.write(responseContent);

out.flush();

}

}

}

第二步:构建Browser对象,例如:

package com.jt.common.net;

import java.io.IOException;

import java.io.InputStream;

import java.net.Socket;

/**

  • 模拟一个简易浏览器(Client)

*/

public class Browser {

public static void main(String[] args) throws IOException {

//1.创建网络编程中的客户端对象(Socket)

//构建Socket对象时要执行连接个计算机(ip),访问计算机中的哪个应用(port)

Socket socket=new Socket(“127.0.0.1”,9999);//TCP

//2.创建一个输入流对象,读取服务端写到客户端的数据

InputStream in = socket.getInputStream();

byte[] buf=new byte[1024];

int len=in.read(buf);

String content=new String(buf,0,len);

System.out.println(content);

//3.释放资源

socket.close();

}

}

第三步:运行tomcat和Browser,检测Browser输出.

也可以打开,浏览器直接访问http://localhost:9999

Day04~Nacos 配置中心入门

============================================================================

核心知识点


  • 配置中心诞生的背景(分布式架构下如何动态发布和更新配置)

  • 市场上主流的配置中心(Nacos,…)

  • Nacos配置中心的基本应用(添加依赖,修改配置文件名以及内容,新建配置,应用配置)

*@RefreshScope注解的应用(描述类,实现类中属性值@Value与配置中心中内容的同步)

常见问题分析


  • 为什么要使用配置中心?(项目上线后实现配置的动态发布和更新)

  • 你知道哪些主流配置中心?

  • Nacos配置中心如何应用?

  • Java项目中你用的日志API是什么?(org.slf4j.Logger)

  • 你项目中为什么使用org.slf4j.Logger对象记录日志?此对象是日志规范,是对外面的门面,可以更好降低耦合

  • @Slf4j注解的作用是什么?(此注解属于lombok,用于描述类,在类中创建org.slf4j.Logger对象)

  • 你知道Java中有哪些常用日志级别?(debug<info<warn<error)

  • Java日志在设计时为什么要设计日志级别?(方便根据级别调整日志输出)

  • Java中日志级别的配置通常要写到哪里?(配置中心)

  • 你觉得Nacos配置中心通常会配置哪些内容?(可能经常变化的数据)

  • Nacos配置中心依赖对项目中配置文件的名字有要求吗?(bootstrap.yml)

  • Nacos中@RefreshScope注解的应用场景以及作用.

  • 如何在初始化对象属性时从配置中心读取配置内容?(@Value注解对属性进行描述)

常见Bug分析


  • idea连接database,例如mysql.(可以baidu,然后输入idea database进行复合查询)

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 配置文件或配置文件格式不正确,例如:

在这里插入图片描述

  • @Value注解包引入错误,例如:

在这里插入图片描述

*@Value配置读取不到,例如:

在这里插入图片描述

课后作业


  • 总结课上知识点,并尝试重新构建项目进行配置实践.

  • 将Nacos配置入门章节的小节节面试仔细读一遍.

  • 预习Nacos的配置模型.

Day05~Nacos配置管理模型

===========================================================================

核心知识点


  • 配置管理模型存在的意义

  • 配置管理模型三要素及其要素关系

  • Nacos中读取指定命名空间和分组下的配置

  • Naocs中的共享配置的设计(对很多配置文件中的共性的一种提取方式)

常见问题分析


  • 如何理解配置的命名空间(Namesapce)?(定义一些配置的作用域,做配置的分类管理,不同环境不同配置)

  • 为什么要进行配置分组?(一个命名空间可以有多个分组,同一个生产环境下的不同活动会有不同配置)

  • 配置中心运行有共享配置吗,如何引用?(可以,基于shared-configs元素进行引用)

  • Java程序中读取不到配置?(依赖,配置文件,命名空间,分组,data-id,空格,缩进,重启,放大招)

常见Bug分析


  • @Value(“${logging.level.com.jt}”) 读取不到值?(先检查你是否有这个配置,假如没有可以给定一个默认值)

  • 线程(Thread)安全问题?(多个线程,共享数据集,原子操作)

  • 如何理解线程并发中的双重校验?(既要保证安全,又要保证效率)

  • 如何理解定时任务?(让线程对象在规定的时间范围内自动去执行任务,例如配置信息的定时刷新)

课后作业


  • 总结课上内容(命名空间,分组,共享配置)

  • 基于Timer对象实现定时任务调度(单线程有顺序的任务调度)

  • 基于ScheduledExecutorService实现一个任务调度(课后拓展,Nacos中的定时心跳,配置长轮询都是基于这个对象)

  • 在ProviderCacheController类中添加一个本地Cache(基于CopyOnWriteArrayList对象实现)

  • 基于双重校验机制,实现类的单实例设计(拓展,自己尝试实现).

  • 预习Sentinel章节的限流操作(北京市为什么要限号)

作业答案


  • 基于Timer对象实现定时任务调度,例如:

package com.jt.common.util;

import java.util.Timer;

import java.util.TimerTask;

import java.util.concurrent.ScheduledExecutorService;

/**

  • 单线程定义任务工具类

*/

public class TimerUtils {

public static void main(String[] args) {

//1.构建执行任务的对象(这里选择java中的Timer对象)

//Timer对象创建时会创建一个线程,并且为线程分配一个任务队列

Timer timer=new Timer();

//2.构建任务对象

TimerTask task1=new TimerTask() {

@Override

public void run() {

System.out.println(System.currentTimeMillis());

//timer.cancel(); 结束任务调度

}

};

//3.定时执行任务

timer.schedule(task1,//要执行的任务

1000,//1秒以后开始执行

1000);//每隔1秒执行1次

//基于Timer类执行定时任务时,最大的缺陷是多个任务不能并发执行.

}

}

  • 基于ScheduledExecutorService实现一个任务调度,例如:

package com.jt.common.util;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

/**

  • 测试多线程任务调度

*/

public class ScheduledExecutorServiceTests {

public static void main(String[] args) {

//构建一个负责任务调度的线程池对象,池中最多有三个核心线程

ScheduledExecutorService ses=

Executors.newScheduledThreadPool(3);

//构建任务对象

Runnable task=new Runnable() {

@Override

public void run() {

String tName=Thread.currentThread().getName();

System.out.println(tName+“->”+System.currentTimeMillis());

}

};

//执行任务对象(定时任务调度):1秒以后开始执行,每隔1秒执行1次

ses.scheduleAtFixedRate(task,

1,//初始延迟

5,//每隔1秒启动1次(与任务是否执行结束无关)

TimeUnit.SECONDS);//时间单位

}

}

  • 在ProviderCacheController类中添加一个本地Cache对象,在保证其线程安全的前提下,提高其性能.

//构建一个本地(Local)缓存对象(基于jvm中的一个对象存储从数据库获取的数据).

private List cache=new CopyOnWriteArrayList<>();

@RequestMapping(“/provider/cache02”)

public List doUseLocalCache02(){

if(!useLocalCache){//假如没有打开本地Cache,则直接访问数据库

System.out.println(“Get data from database”);

return Arrays.asList(“Category-A”, “Category-B”, “Category-C”);

}

if(cache.isEmpty()) {

synchronized (cache) {

if (cache.isEmpty()) {//Thread-A,Thread-B,…

System.out.println(“Get data from database”);

//假设这部分分类信息是从数据库获取的,但是,我不希望每次获取分类信息都要从数据库查

List cates = Arrays.asList(“Category-A”, “Category-B”, “Category-C”);

cache.addAll(cates);

}

}

}

return cache;

}//生产层面

  • 基于双重校验机制,实现类的单实例设计,例如:

package com.jt.common.thread;

/**

  • 如何保证如下类的设计在外界能获取一个实例~单例设计

*/

class Singleton{

private Singleton(){}

private static Singleton instance;

public static Singleton getInstance(){

if(instance==null) {

synchronized (Singleton.class) {

if (instance == null) {//双重校验

instance = new Singleton();

}

}

}

return instance;

}

}

public class SingleTests {

public static void main(String[] args) {

Thread t1=new Thread(){

@Override

public void run() {

System.out.println(Singleton.getInstance());

}

};

Thread t2=new Thread(){

@Override

public void run() {

System.out.println(Singleton.getInstance());

}

};

Thread t3=new Thread(){

@Override

public void run() {

System.out.println(Singleton.getInstance());

}

};

t1.start();

t2.start();

t3.start();

}

}

Day06~Sentinel应用入门

============================================================================

核心知识点


  • 限流的背景

  • Sentinel限流入门(控制台8180-定义规则,客户端服务应用规则:依赖,配置)

  • Sentinel常用限流模式(直接,关联,链路)

  • Sentinel降级入门实现(暂停对服务的访问)

常见问题分析


  • 为什么要进行限流? (系统处理能力有限,可以通过限流方式,保证系统可靠运行)

  • Sentinel限流的基本原理?(底层对请求进行拦截,然后通过流控规则限定对资源访问)

  • Sentinel限流有哪些算法? (计数器,令牌桶,漏桶,滑动窗口算法~sentinel默认)

  • Sentinel常用限流效果有哪些?(快速失败,预热,排队)

常见Bug分析


  • sentinel 服务启动不起来?(要使用JDK8)

  • sentinel 面板不显示我们的服务?(依赖,配置,访问,大招)

课后作业


  • 总结课上知识点.

  • 了解常用限流算法.

  • 尝试基于@SentinelResource注解描述的方法进行限流结果的定义?

  • 预习sentinel降级异常处理,Sentinel热点规则设计,授权设计.

作业答案


  • 基于@SentinelResource注解描述的方法进行限流结果的定义.

第一步:定义blockHandlerClass,例如:

package com.jt.provider.service;

import com.alibaba.csp.sentinel.slots.block.BlockException;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

@Slf4j

@Component

public class ResourceBlockHandler {

/**

  • 注意此方法中的异常类型必须为BlockException (

  • 它是所有限流,降级等异常的父类类型),方法的返回

  • 值类型为@SentinelResource注解描述的返回值类型,

  • 方法的其他参数为@SentinelResource注解描述的方法参数,

  • 并且此方法必须为静态方法

  • @param ex

  • @return

*/

public static String call(BlockException ex){

log.error(“block exception {}”, ex.getMessage());

return “访问太频繁了,稍等片刻再访问”;

}

}

第二步:修改@SentinelResource注解中的属性定义,例如:

@SentinelResource(value=“doGetResource”,

blockHandlerClass = ResourceBlockHandler.class,

blockHandler = “call”)

public String doGetResource(){

return “do get resource”;

}

第三步:在controller方法中,调用@Sentinel注解描述的方法,例如:

/**

  • 演示链路限流

  • @return

*/

@GetMapping(“/sentinel03”)

public String doSentinel03(){

return resourceService.doGetResource();

//return “sentinel 03 test”;

}

Day07~Sentinel应用进阶

============================================================================

核心知识点


  • Sentinel 异常处理

  • Sentinel 热点数据限流

  • Sentinel 系统规则应用实践

  • Sentinel 授权规则应用实践

  • Sentinel 拦截器应用原理分析

常见问题分析


  • 为什么要进行异常处理?(提高用户体验)

  • Sentinel中限流,降级的父类异常类型是什么?(BlockException)

  • Sentinel中默认的BlockException处理对象是谁?(DefaultBlockException)

  • 如何自己定义Sentinel的异常处理对象?(直接或间接继承BlockExceptionHandler)

  • 如何理解热点数据以及限流的方式是什么?(经常访问的数据,基于参数或参数值进行限流)

  • 如何理解sentinel中的系统规则?(全局限流规则,基于QPS,CPU,…)

  • 如何理解Sentinel中的授权规则?(黑白名单)

常见Bug分析


  • 请求被限流时出现500异常?

  • 异常处理对象没有交给Spring管理(例如类使用@Common修饰)

课后作业


  • 总结课上sentinel应用规则

  • 实践Spring MVC中的拦截器应用(重点)

  • 思考客户端向tomcat发起一个请求时,tomcat处理这个请求的过程?

  • 手写一个简易的框架执行链(了解)

  • 手写一个简易的过滤链(了解)

  • 预习微服务中的Gateway组件.

作业答案


  • tomcat 处理客户端的请求时的一个简易流程分析,例如:

在这里插入图片描述

  • 基于Spring MVC中的拦截器实现对控制方法进行时间访问控制?

package com.jt.provider.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.time.LocalTime;

/**

  • Spring MVC 中的拦截器对象,

  • 此对象可以在你执行目标Controller方法之前执行

*/

public class TimeInterceptor implements HandlerInterceptor {

/**

  • 此方法在你执行的目标Controller方法之前执行

  • @return 返回值true表示放行,可以继续执行request的后续业务

*/

@Override

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response,

Object handler) throws Exception {

System.out.println(“=preHandle=”);

//业务:允许在8点之后,晚9点之前可访问

LocalTime now = LocalTime.now();//获取当前时间,

int hour = now.getHour();//获取当前时间的小时单位

if(hour<8||hour>=21)

throw new RuntimeException(“请在规定时间访问8~21”);

return true;

}

}

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

package com.jt;

import com.jt.provider.interceptor.TimeInterceptor;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class SpringWebConfig implements WebMvcConfigurer {

//注册拦截器

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new TimeInterceptor())

.addPathPatterns(“/provider/sentinel01”);

}

}

第三步:对/provider/sentinel01路径按时间段进行访问,检测拦截器的执行.

  • 手写一个简易的框架执行链(了解),模拟框架中执行链的设计,例如:

package com.jt.common.interceptor;

import javax.xml.transform.Source;

import java.time.LocalTime;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;

/**

  • 如何理解框架?设计好的一个半成品?(类似简历模板)

  • 框架设计时会有一些对象的定义以及这些对象的执行流程,类似一个执行链.

  • 在当前案例中,我们模拟一个框架中执行链的设计.

*/

//拦截器接口

interface HandlerInterceptor{

default void before(){}//定义在目标handler方法执行之前执行

default void after(){}//定义在目标handler方法之后执行

}

//处理器接口

interface Handler{

void processed();//处理业务的方法

}

//定义一个执行链

class ExecutionChain{//我是执行链的设计者

//一些拦截器

private List interceptors=

new CopyOnWriteArrayList<>();

//业务处理器

private Handler handler;

public ExecutionChain(List interceptors,Handler handler){

this.handler=handler;

this.interceptors.addAll(interceptors);

}

public void execute(){//负责执行业务的方法(例如处理请求)

//1.before

for(int i=0;i<interceptors.size();i++){

interceptors.get(i).before();

}

//2.processed

handler.processed();

//3.after

for(int i=interceptors.size()-1;i>=0;i–){

interceptors.get(i).after();

}

}

}

public class FrameworkTests {//框架应用者

public static void main(String[] args) {

//应用执行链

//1.创建拦截器

List interceptors=new CopyOnWriteArrayList<>();

HandlerInterceptor interceptor=new HandlerInterceptor() {

@Override

public void before() {

System.out.println(“记录考试开始时间:”+ LocalTime.now());

}

@Override

public void after() {

System.out.println(“记录考试结束时间:”+ LocalTime.now());

}

};

interceptors.add(interceptor);

//2.创建处理

Handler handler=new Handler() {

@Override

public void processed() {

System.out.println(“同学们开始考试”);

}

};

//3.创建执行链

ExecutionChain chain=

new ExecutionChain(interceptors,handler);

//4.执行执行链

chain.execute();

}

}

  • 基于JAVA技术实现一个简易的过滤链?(了解)

在我们的web服务处理请求时,系统底层有一个过滤链,用于对请求做一个预处理,这里做一个简易设计分析,例如:

package com.jt.common.filter;

import java.util.List;

import java.util.concurrent.CopyOnWriteArrayList;

//过滤器(特殊拦截器)

interface Filter{

boolean invoke();

}

//控制器(负责请求分发)

interface Servlet{

void dispatch();

}

//过滤链

class FilterChain{

private List filters=new CopyOnWriteArrayList<>();//过滤器(请求数据过滤)

private Servlet servlet;//控制器(请求控制逻辑)

public FilterChain(List filters, Servlet servlet) {

this.filters.addAll(filters);

this.servlet = servlet;

}

public void doFilter(){//执行过滤链

//请求过滤

for(int i=0;i<filters.size();i++){

if(!filters.get(i).invoke())return;

}

//请求分发

servlet.dispatch();

}

}

public class FilterChainTests {

public static void main(String[] args) {

//1.构建过滤器对象

Filter filter1=new Filter() {

@Override

public boolean invoke() {

System.out.println(“filter 01”);

return true;

}

};

Filter filter2=new Filter() {

@Override

public boolean invoke() {

System.out.println(“filter 02”);

return true;

}

};

List filters=new CopyOnWriteArrayList<>();

filters.add(filter1);

filters.add(filter2);

//2.构建控制器对象

Servlet servlet=new Servlet() {

@Override

public void dispatch() {

System.out.println(“将请求分发给具体对象去执行”);

}

};

//3.执行请求过滤及处理

FilterChain fc=new FilterChain(filters,servlet);

fc.doFilter();

}

}

Day08~网关(Gateway)应用实践

===============================================================================

核心知识点


  • API 网关诞生背景

  • 市场主流微服务网关.

  • Gateway实现服务的保护和转发(重点)

  • Gateway层面的负载均衡实现(重点)

  • Gateway请求处理原理分析(重点)

  • Gateway中的常用谓词对象(了解)

  • Gateway中的常用过滤器(了解)

  • Gateway中基于sentinel实现限流操作(重点)

常见问题分析


  • 网关入门实践的步骤? (依赖,配置,启动,服务访问)

  • 网关项目中的负载均衡是如何实现?(基于Ribbon实现,可以在RibbonLoadBalancerClient中加断点分析)

  • 网关项目中过滤器的类型?(GlobalFilter,GatewayFilter)

  • 网关项目中如何基于sentinel实现服务的限流?(路由id,API分组限流)

  • Idea中如何使用HttpClient客户端工具?(发送post,put等请求,传递请求头参数)

  • Idea中Maven helper插件的安装和应用?

在这里插入图片描述

在这里插入图片描述

  • 网关项目中的请求处理逻辑是如何实现的?(XxxHandlerMapping–谓词逻辑->XxxWebhandler-Filters–>…)

在这里插入图片描述

  • idea中httpclient工具的应用,例如:

在这里插入图片描述

在这里插入图片描述

假如,idea中没有Tools,可以在键盘上按ctrl+shift+a进行查找.

常见BUG分析


  • 配置文件格式不正确,例如

在这里插入图片描述

  • 服务访问被拒绝,例如

在这里插入图片描述

  • 服务注册失败(nacos没启动),例如:

在这里插入图片描述

课后作业


  • 了解过滤链的设计(自己参考课堂代码反复实现)

  • 总结网关的基本应用(服务Netty,请求处理WebFlux,…)

  • 课后了解单点登录系统诞生(SSO)的背景,有什么设计方案?

  • 课后了解一下Spring Security技术(认证,授权),JWT技术?

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

=============================================================================

核心知识点


  • 单点登录系统诞生的背景

  • Java中单点登录系统解决方案.

  • 单点登录系统(SSO)中的服务划分及关系设计

  • 单点登录系统中父工程的创建及初始化

  • 系统基础服务(sso-system)工程的创建及基本业务实现

  • 认证服务(sso-auth)工程的创建及初始化

常见问题分析


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

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

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

  • 用户登录时,需要从数据库查询哪些信息?(用户信息以及用户的权限信息)

  • 如何基于用户id查询用户权限,你有什么方案?

  • 基于idea的为类自动生成序列化id?

在这里插入图片描述

  • 基于idea中的httpclient进行服务访问测试?

在这里插入图片描述

  • 如何将链接数据库的信息写到配置中心?

在这里插入图片描述

最后,附一张自己面试前准备的脑图:

image

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

image

  • Spring全家桶(实战系列)

image.png

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

image

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取


  • 了解过滤链的设计(自己参考课堂代码反复实现)

  • 总结网关的基本应用(服务Netty,请求处理WebFlux,…)

  • 课后了解单点登录系统诞生(SSO)的背景,有什么设计方案?

  • 课后了解一下Spring Security技术(认证,授权),JWT技术?

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

=============================================================================

核心知识点


  • 单点登录系统诞生的背景

  • Java中单点登录系统解决方案.

  • 单点登录系统(SSO)中的服务划分及关系设计

  • 单点登录系统中父工程的创建及初始化

  • 系统基础服务(sso-system)工程的创建及基本业务实现

  • 认证服务(sso-auth)工程的创建及初始化

常见问题分析


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

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

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

  • 用户登录时,需要从数据库查询哪些信息?(用户信息以及用户的权限信息)

  • 如何基于用户id查询用户权限,你有什么方案?

  • 基于idea的为类自动生成序列化id?

在这里插入图片描述

  • 基于idea中的httpclient进行服务访问测试?

在这里插入图片描述

  • 如何将链接数据库的信息写到配置中心?

在这里插入图片描述

最后,附一张自己面试前准备的脑图:

[外链图片转存中…(img-IKDSL5Y1-1715786722776)]

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

[外链图片转存中…(img-f0rpltOg-1715786722777)]

  • Spring全家桶(实战系列)

[外链图片转存中…(img-wMDAe9m4-1715786722777)]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-pHqYZvwE-1715786722777)]

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值