MySQL多个Sending Data状态的进程导致SQL执行查询耗时长
场景数据量十几万的数据表,一个简单的 join 联表查询平均耗时 30s 以上。
123456789101112131415161718192021222324252627282930SELECT esa.ID, esa.EVENT_CODE, esa.HAPPEN_TIME, esa.EVENT_LEVEL, esa.HOST_NAME, esa.SYSTEM_NAME, si.SYSTEM_NAME AS source, esa.ALARM_GROUP, esa.EVENT_DETAIL, esa.POINT_STATUS, esa.HANDLE_STATUS, esa.CONFIRM_STATUS, esa.IS_SHIELD, esa.POINT_ID, esa.HAS_EXPERT_STORE, concat( '/img', esa.PIC_URL ) PIC_URL, esa.IS_SIMULATE, esa.ASSET_ID, esa.IS_CONTACT_ASSET FROM event_signal_actual esa LEFT JOIN su ...
网站实现扫描二维码关注公众号登录
场景某个网站需要以关注公众号的方式登录,简化登录方式,和为微信公众号引流。
扫码登陆流程
代码实现
后端创建二维码 ticket 返回给前端。每次创建二维码ticket需要提供一个开发者自行设定的参数(scene_id),有临时二维码和永久二维码。创建临时二维码示例如下:
12345678@GetMapping("/ticket")public ApiResponse<JSONObject> getTicket() { // 将uuid作为场景值 String sceneId = IdUtil.fastUUID(); WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(sceneId, 1800); return ApiResponse.ofSuccess(new JSONObject().fluentPut("ticket", ticket.getTicket()) .fluent ...
微信公众号访问第三方网页授权流程
场景某医院官网微信公众号,需要添加一个“个人报告”菜单,点击跳转到第三方网页,提供查询缴费记录、影像报告等功能。
公众号网页授权流程
第三方网页有自己的身份认证框架,前端 VUE ,后端 Spring Boot 。
代码实现(前端处理回调地址)
用户在微信客户端中访问第三方网页,若后端校验当前用户未登录,返回 401 状态码和微信授权页面 url 。
1234567891011121314151617181920@AllArgsConstructor@Componentpublic class AuthenticationEntryPointImpl implements AuthenticationEntryPoint{ private final SecurityProperties properties; @Override public void commence(HttpServletRequest request, HttpServletResponse httpServletResponse, AuthenticationException ...
理解OAuth2.0
概述名词定义资源所有者(Resource Owner):通常是用户,拥有受保护资源的权限。
客户端(Client):希望访问资源服务器上的资源的应用程序,可能是网站、移动应用或其他服务。
授权服务器(Authorization Server):负责验证资源所有者的身份并发放访问令牌,通常与资源服务器是分开的。
资源服务器(Resource Server):存储受保护资源的服务器,负责提供资源并验证访问令牌。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。
对资源服务器的理解场景一:微信公众号的网页授权机制,用户在微信公众号中访问第三方网页,可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。Resource Owner 就是微信用户;Client 就是第三方网页;Authorization server 就是微信的认证服务器,负责发放访问令牌;Resource server 就是微信的服务器,负责提供微信用户信息。
在场景一中,如果第三方网页是由 Vue + Spring 前后端分离架构实现,那么客户端就是指 Vue 前端和 Spring 后端这个整体框架。
在 ...
SSE实时通讯
SSE在 Spring Boot 中实现实时通信可以使用多种技术和组件。以下是一些常用的实时通信方案:
WebSocket
Server-Sent Events(SSE)
SSE(Server-Sent Events)是基于 HTTP 的单向通信机制。它允许服务器通过单个 HTTP 连接将实时事件流推送到客户端。SSE 是一种轻量级的实时通信协议,适合于服务器向客户端发送实时更新的场景。SSE 建立在常规的 HTTP/HTTPS 协议之上,不需要特殊的网络配置或协议升级,因此易于实现和部署。客户端使用 EventSource API 来接收服务器发送的事件,并对事件进行处理。
WebSocket 是一种全双工的双向通信协议,可以在客户端和服务器之间建立持久的双向连接。WebSocket 建立了一个长久的连接通道,可以在客户端和服务器之间实时地发送消息。相比于 SSE,WebSocket 提供了双向通信的能力,允许客户端和服务器之间进行双向的实时数据交换。WebSocket 是一个独立的协议,它通过 HTTP 握手进行协议升级,之后通过保持长连接实现实时通信。客户端和服务器 ...
Frp内网穿透,实现本地接口测试微信回调通知
场景微信的支付回调通知 API 中,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。
http://localhost:8080/pay/transactions/native/notify 为本地微信支付回调地址,通过 frp 内网穿透回调本地接口进行 debug 测试。
预期效果一台公网服务器和域名 frp.liuzx.com.cn ,其中 80 端口已被 Nginx 监听占用。
本地接口 http://localhost:8080/test ,实现以下访问方式:
http://frp.liuzx.com.cn/test(直接域名不带端口访问)
https://frp.liuzx.com.cn/test(https 访问)
http://frp.liuzx.com.cn:8080/test(域名 + 端口访问)
http://ip:8080/test(IP + 端口访问)
不能停止 Nginx 服务,意味着 Frp 与 Nginx 需要同时使用 80 端口。主要思路就是通过 Nginx 转发到 Frp 监听的 HTTP 请求端口。
Frp实现内网穿透Frp ...
虚拟内存
虚拟内存、物理内存、硬盘空间三者的关系物理内存:物理内存指通过物理内存条而获得的内存空间,称为RAM。
虚拟内存:虚拟内存是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存。用作虚拟内存的磁盘空间被称为交换空间(又称 swap 空间)。
作为物理内存的扩展,Linux 会在物理内存不足时,使用交换分区的虚拟内存,更详细地说,就是内核会将暂时不用的内存块信息写到交换空间,这样一来,物理内存得到了释放,这块内存就可以用于其他目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。
虚拟内存的作用虚拟内存可以使得进程对运行内存超过物理内存大小。
为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都是一样的,但分布到物理地址内存是不一样的。作为程序,也不用关心物理地址的事情。
每个进程都有自己的虚拟空间,而物理内存只有一个,所以当启用了大量的进程,物理内存必然会很紧张,于是操作系统会通过内存交换技术,把不常使用的内存暂时存放到硬盘(换出), ...
Systemd守护进程
场景docsify 启动的服务进程经常挂掉,使用 Systemd 设置守护进程,崩溃或退出后自动重启服务。
Systemd和systemctl的关系Systemd 是 Linux 的一个服务管理器,用于启动、停止、管理和监视 Linux 上的各种服务和守护进程;而 systemctl 是与 Systemd 集成的用于控制和管理服务的命令行工具。
systemctl设置守护进程
创建 Systemd 服务单元文件:在 /etc/systemd/system/ 目录下创建一个以 .service 结尾的文件,比如 docsify.service。
1sudo vim /etc/systemd/system/docsify.service
添加以下内容:
123456789101112131415[Unit]# 服务的描述。Description=docsifyAfter=network.target[Service]# 服务运行的用户名。User=root# 启动命令ExecStart=/usr/local/bin/docsify serve /root/docs# 设置服务在崩溃或退出 ...
Shell脚本解释器
sh script.sh和./script.sh的区别
sh script.sh 是使用系统上的默认Shell解释器来执行脚本文件,忽略脚本中的 shebang 行(例如 #!/usr/bin/expect -f)。
一般在 Linux 系统中,默认的 /usr/bin/sh 默认指向 /usr/bin/bash 的符号链接。
./script.sh 是通过脚本中的 shebang 行(一般都是 #! 开头的第一行)指定的解释器来运行脚本。
指定解释器执行shell脚本的方式假设希望指定 expect 解释器执行脚本,方式如下:
在 shell 脚本中的 shebang 行(第一行)指定解释器。
1#!/usr/bin/expect -f
使用 ./script.sh 的方式运行脚本即可。
使用 expect 命令来执行脚本,这种方式是直接指定 expect 解释器来执行脚本,忽略脚本中的 shebang 行。
1expect script.sh
Nginx server块匹配顺序
在 Nginx 中,server_name 的匹配顺序遵循以下规则:
精确匹配:如果请求的主机名与某个 server 块的 server_name 完全匹配,则使用该 server 块处理请求。
通配符前缀匹配:如果请求的主机名与某个 server 块的 server_name 以通配符(*.)开头的部分匹配,则使用该 server 块处理请求。通配符匹配可以用于处理子域名的请求。
长度最长匹配:如果有多个 server 块的 server_name 部分匹配请求的主机名,则使用最长匹配的 server 块处理请求。这意味着 Nginx 会选择最能精确匹配请求主机名的 server 块。
默认服务器:如果以上规则都不匹配,则使用配置文件中定义的第一个 server 块作为默认服务器块来处理请求。
123456789101112131415161718192021222324252627282930313233343536server { listen 80; server_name liuzx.com.cn; location / { add_hea ...