当前位置: 首页 > wzjs >正文

创新的响应式网站建设优化关键词快速排名

创新的响应式网站建设,优化关键词快速排名,wordpress美化博客,中国域名注册webMVC和webFlux 这是spring framework提供的两种不同的Web编程模型应用场景:用 WebMvc: 项目依赖 Servlet 生态、需要简单同步代码,或使用阻塞式数据库(如 MySQL JDBC)。用 WebFlux: 需要高并发&#xff…

webMVC和webFlux

这是spring framework提供的两种不同的Web编程模型

在这里插入图片描述

应用场景:

  • 用 WebMvc:
    项目依赖 Servlet 生态、需要简单同步代码,或使用阻塞式数据库(如 MySQL + JDBC)。

  • 用 WebFlux:
    需要高并发(如每秒万级请求)、低资源消耗,或已使用响应式技术栈(如 MongoDB Reactive、Kafka)。

springcloud -gateway

在 Spring Cloud Gateway 中,请求处理默认是基于 异步非阻塞 模型的,这是由其底层使用的 Reactor Netty 和 WebFlux 框架决定的。

你说是gateway是异步的,但是一个请求不还是要等待下游服务器的响应吗?这不还是同步吗?
nonono~
[EventLoop线程] 接收请求 → 发起网络调用 → 立即释放 → 处理其他请求

[IO完成回调] → 收到响应 → 继续处理
实际上:

  • 同一个线程可以交替处理多个请求的不同阶段
  • 等待IO时不占用线程(线程可以去处理其他请求)
  • 基于回调/事件机制,IO完成后会通知系统

在这里插入图片描述

gateway是基于WebFlux的,理由也很合理:
webMVC 最高只能有200并发,而已经到微服务级别的应用,很明显并发量肯定不会少,网关层面肯定不能用同步去做,异步是最好最确切的选择。

ContextHolder在同步/异步模式中的实现

contextHolder 个人理解,就是一个全局变量,但是这"全局"是‘一个线程’的范围

专业的说: 基于 线程/上下文隔离 的临时数据存储,生命周期与请求或线程绑定

必要性:

  • 解耦业务代码:
    避免在方法参数中层层传递上下文(如用户身份、跟踪ID)。

  • 在拦截器、Service 层、日志工具等地方都能访问统一上下文。

原生Servlet–request.setAttribute

  • Servlet规范本身并未直接定义线程级别的共享变量接口,只定义了会话范围的HttpSession
  • 但是可以通过ServletRequest获取,因为在Servlet规范中,每个请求都是由容器分配的独立线程处理,ServletRequest 和 ServletResponse 对象天然与线程绑定

在这里插入图片描述

tomcat 容器内部 则通过ThreadLocal关联了请求和线程。如果开发者使用ThreadLocal,需要自行清理(存在风险)

WebMvc–ThreadLocal

不同于原生Servlet,这个ThreadLocal不是Tomcat容器给的,而是Springmvc框架本身提供的。

此时: Tomcat 不直接使用 ThreadLocal 存储 Spring MVC 的请求信息,它只是提供了线程模型(每个请求一个线程),而 Spring MVC 在此基础上利用 ThreadLocal 存储请求相关的上下文。

如果自定义使用:

  1. 定义ThreadLocal工具类
public class MyThreadLocalContext {private static final ThreadLocal<String> currentTenantId = new ThreadLocal<>();public static void setTenantId(String tenantId) {currentTenantId.set(tenantId);}public static String getTenantId() {return currentTenantId.get();}public static void clear() {currentTenantId.remove(); // 防止内存泄漏}
}
  1. 在 Filter/Interceptor 中设置和清理

ThreadLocal的隐式线程绑定

在工具类中你会发现,其实set/get过程并没有关联任何的线程ID

这是因为,ThreadLocal内部实现了自动关联线程ID
在这里插入图片描述

WebFlux

ThreadLocal已经无法处理异步请求的问题了,因为异步请求一般都存在线程的切换

springcloud-gateway提供了几种机制来处理这个问题

1. Reactor Context

2. TransmittableThreadLocal

简称 (TTL) 是阿里开源的一个线程本地变量工具,它是对 Java 标准 ThreadLocal 的增强,主要解决了线程池等异步执行场景下的线程变量传递问题。

使用:

  1. 定义TransmittableThreadLocal工具类
package com.ruoyi.common.core.context;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.StringUtils;/*** 获取当前线程变量中的 用户id、用户名称、Token等信息 * 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取** @author ruoyi*/
public class SecurityContextHolder
{/*** 既然springboot中默认用的是同步请求,必须等待响应完成,为什么这里用异步的threadlocal去存储?** 1.  防御性编程,为未来的异步拓展预留空间** 2.  即时外部请求是重构的,框架内部可能使用线程池处理一些异步任务* 比如日志记录:* @GetMapping("/user/info")*     public UserInfo getUserInfo() {*         // 同步设置用户上下文*         SecurityContextHolder.setUserId("123");**         // 同步操作*         UserInfo info = userService.getInfo();**         // 异步记录日志(很常见的需求)*         logAsync("User info accessed"); // 内部使用线程池,内部会用contextHolder获取到用户信息,**         return info;*     }* 3. springcloud-gateway中请求默认是异步非阻塞的,原因是它是webflux编程*/private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();public static void set(String key, Object value){Map<String, Object> map = getLocalMap();map.put(key, value == null ? StringUtils.EMPTY : value);}public static String get(String key){Map<String, Object> map = getLocalMap();return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));}public static <T> T get(String key, Class<T> clazz){Map<String, Object> map = getLocalMap();return StringUtils.cast(map.getOrDefault(key, null));}public static Map<String, Object> getLocalMap(){Map<String, Object> map = THREAD_LOCAL.get();if (map == null){map = new ConcurrentHashMap<String, Object>();THREAD_LOCAL.set(map);}return map;}public static void setLocalMap(Map<String, Object> threadLocalMap){THREAD_LOCAL.set(threadLocalMap);}public static Long getUserId(){return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L);}public static void setUserId(String account){set(SecurityConstants.DETAILS_USER_ID, account);}public static String getUserName(){return get(SecurityConstants.DETAILS_USERNAME);}public static void setUserName(String username){set(SecurityConstants.DETAILS_USERNAME, username);}public static String getUserKey(){return get(SecurityConstants.USER_KEY);}public static void setUserKey(String userKey){set(SecurityConstants.USER_KEY, userKey);}public static String getPermission(){return get(SecurityConstants.ROLE_PERMISSION);}public static void setPermission(String permissions){set(SecurityConstants.ROLE_PERMISSION, permissions);}public static void remove(){THREAD_LOCAL.remove();}
}
  1. 在拦截器中添加和删除
/*** 自定义请求头拦截器,将Header数据封装到线程变量中方便获取* 注意:此拦截器会同时验证当前用户有效期自动刷新有效期** @author ruoyi*/
public class HeaderInterceptor implements AsyncHandlerInterceptor
{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{if (!(handler instanceof HandlerMethod)){return true;}SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));String token = SecurityUtils.getToken();if (StringUtils.isNotEmpty(token)){LoginUser loginUser = AuthUtil.getLoginUser(token);if (StringUtils.isNotNull(loginUser)){AuthUtil.verifyLoginUserExpire(loginUser);SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);}}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception{SecurityContextHolder.remove();}
}

TTL底层依赖ThreadLocal,但是它的核心是 跨线程传递 ThreadLocal 值
具体怎么做到的:父子线程之间的值传递

http://www.dtcms.com/wzjs/80671.html

相关文章:

  • 怎么黑掉织梦做的网站百度提问登陆入口
  • 美国房产网站成都seo网络优化公司
  • aspcms 网站地图企业网站seo平台
  • 外贸网站找人建设百度竞价广告怎么投放
  • 沈阳市城乡建设委员会网站软文公司代写
  • 三亚放心游app官方网站自媒体是什么
  • 夸克搜索网页版荆州网站seo
  • 门户网站如何做谷歌seo网站seo优化检测
  • 做资源下载网站条件信息流优化师工作内容
  • 千图网的主要功能无锡网站seo
  • 360报危险网站搜狗推广登录平台
  • 上海网站空间服务器苏州seo关键词优化排名
  • 网站弹出框怎么做网络推广文案
  • 农村电商网站建设方案郑州关键词优化费用
  • 贵州城乡和建设厅网站怎么样进行网络推广
  • 自己做网站语言构建服务器网推平台
  • 江苏专业做网站南京今天重大新闻事件
  • 做一款小说网站滕州百度推广
  • 邹平市建设局官方网站银川网站seo
  • 网络规划设计师企业数据中心机房建设网站seo方案模板
  • 网站流量如何突破南京疫情最新情况
  • 国内建站 wordpressseo指的是搜索引擎
  • 景德镇建设网站软文营销常用的方式是什么
  • 大学培训中心网站建设登封网络推广
  • 大连建设厅网站seop
  • 移动端网站开发标题设置seo软件服务
  • wordpress悬浮导航代码郑州技术支持seo
  • 怎么做网站导航高级seo是什么职位
  • 百度网站的结构网站快速收录的方法
  • 网站建设推广培训网页设计模板素材图片