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

Docker手动重构Nginx镜像,融入Lua、Redis功能

核心内容:Docker重构Nginx镜像,融入Lua、Redis功能

文章目录

  • 前言
  • 一、准备工作
    • 1、说明
    • 2、下载模块
    • 3、Nginx配置文件
    • 3、Dockerfile配置文件
    • 3、准备工作全部结束
  • 二、构建镜像
  • 三、基于镜像创建容器
  • 三、lua脚本的redis功能使用
  • 总结


前言



⁣⁣⁣⁣ ⁣⁣⁣⁣ 哈喽,各位it同学们好,今天内容主要是:去重构nginx镜像,融入lua、Redis功能,能防范CC攻击,搭建合理有效的WAF 。我知道可能有不少人说OpenResty 已经做了这个事情,他也能去运行lua脚本防范CC攻击,除此之外还有一些流量监测、流量黑洞、蜜罐技术等等,但是今天我没有借用这些方式,就是单纯的想去加强一下nginx,让他去融入这些lua功能,然后我自己去写代码,进行流量的颗粒度控制。 我在网上也看了不少的文章去增强Nginx,但是好多都不全,而且复刻不成功,今天的话,我就记录一下我的做法。在开始之前需要强调一下,生成的镜像他本身还是Nginx,只是给他增强融入lua!!!


提示:以下是本篇文章正文内容,下面案例可供参考。以下教程,本人在4个服务器上面完美复刻,都是经过测试的,跟着我的笔记,你也可以的。



一、准备工作



 ⁣⁣⁣⁣ ⁣⁣⁣⁣ 准备工作其实就是下载东西,还有准备一些初始配置文件。

1、说明

⁣⁣⁣⁣ ⁣⁣⁣⁣ Nginx 执行 Lua 脚本的核心依赖是:
 ⁣⁣⁣⁣ ⁣⁣⁣⁣ - LuaJIT
 ⁣⁣⁣⁣ ⁣⁣⁣⁣ - ngx_devel_kit
 ⁣⁣⁣⁣ ⁣⁣⁣⁣ - lua-nginx-module

⁣⁣⁣⁣ ⁣⁣⁣⁣ 这3个非常重要!!!残缺、版本不一致都会使重构镜像失败!很多重构Nginx镜像都是失败在版本不一致的问题!下载模块里面的版本,都是个人搜集资料和多次尝试之后,搭配出来最优解的版本!这些版本在一起不会出错
 
 ⁣⁣⁣⁣ ⁣⁣⁣⁣ 准备的东西一共是10个,8个下载文件、1个nginx配置文件、1个Dockerfile。


2、下载模块


⁣⁣⁣⁣ ⁣⁣⁣⁣ 其实很多的教程,他都是要让你去在构筑镜像中去下载的,少的文件,没有问题,但是如果非常多的话,而且访问的链接、版本不一致的话,就会出错误,好多下载的东西都是国外的,很慢的。所以为了避免这些问题,这里我是全部都下载好,然后去放在Dockerfile同级的目录下


⁣⁣⁣⁣ ⁣⁣⁣⁣ 下面所有的链接截止(2025年.5月.6日时)全部能正常下载!!! 下载好之后就可以去和dockerfile放在同一个目录,而且要注意文件名字!!!链接有些是在国外,网络延迟大,可能需要多试一试,才能下载!


下面是下载的8个链接

下载的OpenSSL模块,1.1.1u版本 :

https://www.openssl.org/source/openssl-1.1.1u.tar.gz

下载的ngx_devel_kit模块,v0.3.0版本 :

https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz

下载的lua-nginx-module模块,v0.10.21版本 :

https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.21.tar.gz

下载的nginx源码:
Nginx 1.20.2 是非常稳定的 LTS(长期支持)版本

nginx 1.20.2版本   http://nginx.org/download/nginx-1.20.2.tar.gz

下载luajit2的源码,luajit2版本:

 git clone https://github.com/openresty/luajit2.git

下载lua-resty-core模块:

手动去如下地址下载源代码,下载之后将lua-resty-core-v0.1.17改为:lua-resty-core

v0.1.17版本   https://github.com/openresty/lua-resty-core/releases/tag/v0.1.17

下载lua-resty-lrucache模块:

git clone https://github.com/openresty/lua-resty-lrucache.git

下载luarocks-3.9.2的命令模块,版本3.9.2 :

 https://luarocks.org/releases/luarocks-3.9.2.tar.gz

链接有些是在国外,网络延迟大,可能需要多试一试,才能下载!!!
链接有些是在国外,网络延迟大,可能需要多试一试,才能下载!!!
链接有些是在国外,网络延迟大,可能需要多试一试,才能下载!!!


3、Nginx配置文件


⁣⁣⁣⁣ ⁣⁣⁣⁣ 这个是要用到的默认Nginx配置文件!

nginx.conf 如下:

worker_processes  1;events {worker_connections  1024;
}http {################################# 下面是核心内容,必须包含,否则会报各种错!# Nginx 的日志直接输出到标准输出,方便 docker logs 查看,同时也要注意-v挂载的日志路径问题!!access_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log warn;# 显式添加 lua_package_path 路径lua_package_path "/opt/luarocks-3.9.2/lua_modules/share/lua/5.1/?.lua;;";# 确保 resty.core 启动时被加载,避免运行时缺模块init_by_lua_block {require "resty.core"}#################################include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;#gzip  on;server {listen       80;server_name  localhost;location / {root   /usr/share/nginx/html; #必须修改为:/usr/share/nginx/htmlindex  index.html index.htm;}}
}

这个nginx.conf我是进行精简过的!!!核心的内容一定不可少!构筑镜像的过程中需要这些!!!同时挂载也需要!



3、Dockerfile配置文件


⁣⁣⁣⁣ ⁣⁣⁣⁣ 所有点路径问题、报错问题,都已经解决了,可以直接抄!而且也可以作为通用模板!下面代码我都加上注释了!


# 指定基础镜像
FROM centos:7# 替换 yum 源为阿里云镜像,解决 DNS 和网络问题
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo# 安装Nginx和 LuaJIT 所需的依赖
RUN yum update -y && yum install -y \gcc make pcre-devel zlib-devel openssl-devel wget curl unzip git# 编译和安装 LuaJIT
# 编译后的 LuaJIT 会被安装到 Docker 容器的文件系统中,具体路径为 /usr/local/,这是默认的安装目录。
# 系统环境变量会指向 LuaJIT 的库和头文件所在的位置,这样 Nginx 在编译时能够找到并链接 LuaJIT。
WORKDIR /opt
COPY luajit2 /opt/luajit2
# 进入目录并编译安装
WORKDIR /opt/luajit2
RUN make && make install# 设置环境变量 。这里的文件路径和上面是自动保持一致的,不需要改!
# 在编译 Nginx 时用到了 LuaJIT,那么这里就是显式告诉他 LuaJIT 的头文件和库在哪里等等
ENV LUAJIT_LIB=/usr/local/lib
ENV LUAJIT_INC=/usr/local/include/luajit-2.1#下载并解压 OpenSSL 1.1.1u 源码 ,准备好 OpenSSL 源码,为后续 Nginx 编译链接使用。
COPY openssl-1.1.1u.tar.gz /opt/
WORKDIR /opt
RUN tar -zxvf openssl-1.1.1u.tar.gz#  lua-nginx-module 的底层依赖模块,提供宏和功能(如请求上下文、共享内存等)支持 Lua 脚本在 Nginx 中运行。
#  简单说:没它,lua-nginx-module 编译就失败,运行也不行。
COPY ngx_devel_kit-0.3.0.tar.gz /opt/
WORKDIR /opt
RUN tar -zxvf ngx_devel_kit-0.3.0.tar.gz# 这段代码的作用下载 Nginx 模块源码,为编译做准备。
# 这两部分源码是后续编译支持 Lua 的 Nginx 所必须的。
COPY nginx-1.20.2.tar.gz /opt/
WORKDIR /opt
RUN tar -zxvf nginx-1.20.2.tar.gz# 这段代码的作用下载 lua-nginx-module模块源码,为编译做准备。 
COPY lua-nginx-module-0.10.21.tar.gz /opt/
WORKDIR /opt
RUN tar -zxvf lua-nginx-module-0.10.21.tar.gz# -------------------------------
# 安装 Luarocks
COPY luarocks-3.9.2 /opt/luarocks-3.9.2
WORKDIR /opt/luarocks-3.9.2
# 给 configure 文件增加执行权限
RUN chmod +x ./configure
RUN ./configure --with-lua-include=/usr/local/include/luajit-2.1 && make && make install
#  检查是否安装成功
RUN luarocks --version 
# -------------------------------# -------------------------------
# 安装 lua依赖的redis模块
RUN yum install -y gcc make unzip wget readline-devel
RUN yum install -y lua-devel
RUN luarocks install lua-resty-redis
#  检查是否安装成功
RUN find /usr/local -name redis.lua
# -------------------------------# 编译 Nginx
# Nginx 编译 Nginx + Lua 模块时,只需要 lua-nginx-module 和 LuaJIT。
# 这部分代码的作用是编译 Nginx,使其支持 LuaJIT 和 lua-nginx-module 模块。手动编译 Nginx 的过程。
# WORKDIR /opt/nginx-1.24.0:进入 Nginx 源码目录。
# ./configure:配置 Nginx 编译参数:
# --prefix=/etc/nginx:指定自定义编译好的Nginx安装目录。
# --with-cc-opt=... 和 --with-ld-opt=...:让编译器正确找到 LuaJIT 的头文件和库。
# --add-module=...:添加 lua-nginx-module 模块,支持 Lua 脚本。
# --with-openssl=/opt/openssl-1.1.1u 告诉Nginx编译器:使用我指定的源码重新编译并集成进 Nginx,这样能让 Nginx 支持新版本的 TLS/SSL 加密功能。
# --with-http_ssl_module:启用 HTTPS 支持。
# --with-http_stub_status_module:启用 Nginx 状态监控模块。
# make && make install:编译并安装 Nginx。
WORKDIR /opt/nginx-1.20.2
RUN ./configure --prefix=/etc/nginx \--with-cc-opt="-O2 -Wno-error -I/usr/local/include/luajit-2.1" \--with-ld-opt="-L/usr/local/lib -Wl,-rpath,/usr/local/lib" \--add-module=/opt/lua-nginx-module-0.10.21\--add-module=/opt/ngx_devel_kit-0.3.0\--with-openssl=/opt/openssl-1.1.1u \--with-http_ssl_module \--with-http_stub_status_module \
&& make && make install# 下面两个 lua-resty-core 和 lua-resty-lrucache 是 运行时 Lua 模块,不影响Nginx编译。
# 安装 lua-resty-core 和 lua-resty-lrucache 模块(解决 'resty.core' 报错)WORKDIR /opt
COPY lua-resty-core /opt/lua-resty-core
# 将 lua-resty-core 中的 lib/resty 目录复制到容器的 /usr/local/share/lua/5.1 目录下
RUN cp -r /opt/lua-resty-core/lib/resty /usr/local/share/lua/5.1/WORKDIR /opt
COPY lua-resty-lrucache /opt/lua-resty-lrucache
# 将 lua-resty-lrucache 中的 lib/resty 目录复制到容器的 /usr/local/share/lua/5.1 目录下
RUN cp -r /opt/lua-resty-lrucache/lib/resty /usr/local/share/lua/5.1/# 复制自定义的 Nginx 配置文件
# 这一步只是将默认的配置文件复制到容器中,它本身并不会执行任何操作,只是保证 Nginx 在容器中启动时会使用你自定义的配置文件。
# 到时候我们在启动容器时,通过 -v 参数将宿主机上的配置文件挂载到容器中,这样 Nginx 就会使用我们自定义的配置文件了。
# 这一步非常重要!!!
COPY nginx.conf /etc/nginx/nginx.conf  # 添加配置文件和启动脚本
# 声明容器对外暴露 80 端口(HTTP)。
EXPOSE 80
CMD ["/etc/nginx/sbin/nginx", "-g", "daemon off;"]# /etc/nginx/sbin/nginx含义:来启动 Nginx,注意哦!这里的路径是编译后的Nginx的路径,上面我们已经指定的!!!
# 
# daemon off含义:设置容器启动时运行的命令,让 Nginx 以前台模式启动并保持运行(不进入守护进程),这样 Docker 容器才不会退出,Nginx 会持续运行。

⁣⁣⁣⁣ ⁣⁣⁣⁣ dockerfile文件都是写好的,直接复制就行了!!!问题都解决了!!!


3、准备工作全部结束


⁣⁣⁣⁣ ⁣⁣⁣⁣ OK!到这里基本上所有的东西全部准备齐了!!!一定要确保其名字、文件层级关系如下

在这里插入图片描述

一共10个文件!!! 下面就是重构镜像!!!





二、构建镜像


⁣⁣⁣⁣ ⁣⁣⁣⁣ 如果之前的构建过程中出现了错误并留下了不完整的文件,可能会导致后续构建失败。可以尝试清理之前的构建缓存,并重新构建,不会对你的容器、镜像、数据卷或系统本身造成危害。清理 Docker 缓存的命令

docker builder prune

⁣⁣⁣⁣ ⁣⁣⁣⁣ 我的建议是在重构镜像前面执行一次,根据我的实操经验,他会影响构建镜像!

⁣⁣⁣⁣ ⁣⁣⁣⁣ OK!!!正式开始!

⁣⁣⁣⁣ ⁣⁣⁣⁣ --no-cache :禁用缓存

docker build --no-cache -t nginx-lua:1.20.2 .

如下:
在这里插入图片描述
在这里插入图片描述


⁣⁣⁣⁣ ⁣⁣⁣⁣ 我的重构花费300多秒!!!如果他还要去下载东西,估计要更多的时间!!!这个重构,可能会受网络失败!你再去执行一下就可以了!!!



三、基于镜像创建容器


⁣⁣⁣⁣ ⁣⁣⁣⁣  注意!挂载的目录必须先创建,而且注意权限问题! 还要注意一点!!那就是把之前的dockerfile文件同级目录下的nginx.conf文件,要去放到/mydata/nginx_lua/conf/nginx.conf目录下!!必须的!!!不然报错的!!!


然后执行下面的命令:

docker run --name  nginx-lua -p 80:80 \-e TZ=Asia/Shanghai \-v /mydata/nginx_lua/html:/usr/share/nginx/html \-v /mydata/nginx_lua/conf/nginx.conf:/etc/nginx/conf/nginx.conf \-v /mydata/nginx_lua/page:/mydata/nginx_lua/page \-v /mydata/nginx_lua/lua/waf_limit.lua:/mydata/nginx_lua/lua/waf_limit.lua \-v /mydata/nginx_lua/logs:/var/log/nginx \-d  nginx-lua:1.20.2

这个时候就容器就创建好了!!!


下面可以去测试一下!!!

        #在server模块里面,随便找个地方添加下面的代码location /lua {default_type 'text/plain';content_by_lua 'ngx.say("hello, lua")';}

访问如下:
在这里插入图片描述

到这里只能说明你的功能等等各方面没有问题的!!!!


OK,下面我们去测试lua的redis模块!!!





三、lua脚本的redis功能使用


我给我的模块加上(粒度控制,加在谁的上面,谁起作用,贼好玩):

        location /ithe {access_by_lua_file /mydata/nginx_lua/lua/waf_limit.lua;alias  /mydata/nginx_lua/page; }

目录如下:
在这里插入图片描述




waf_limit.lua内容如下

这个脚本主要的作用就是:基于 IP + User-Agent 组合做访问频率限制(限流防护),防范 CC 攻击。直接复制就可以了(要改一下redis的账号密码)!!!!


-- 工具函数:获取真实 IP(考虑了反向代理)
local function get_client_ip()local headers = ngx.req.get_headers()local ip = headers["X-Real-IP"] or headers["X-Forwarded-For"] or ngx.var.remote_addrif ip and type(ip) == "string" then-- 处理多级代理下的多个IP地址(取第一个)local first_ip = ip:match("([^,]+)")return first_ipendreturn "unknown"
end-- 获取请求相关信息
local client_ip = get_client_ip()                  -- 访问者真实 IP
local user_agent = ngx.var.http_user_agent or ""   -- User-Agent-- 打印日志(方便调试)
ngx.log(ngx.ERR, "-----------------------------------[WAF] start:-------------------------------- ")
ngx.log(ngx.ERR, "############# [WAF] IP: ", client_ip," #############")
ngx.log(ngx.ERR, "############# [WAF] User-Agent: ", user_agent," #############")
ngx.log(ngx.ERR, "############# [WAF] URI: ", ngx.var.uri," #############")------------------------------------------------------------------------- 连接 Redis(默认连接 127.0.0.1:6379)
local redis = require "resty.redis"
local red = redis:new()-- 尝试连接远程 Redis(请替换成你的实际 IP 和端口)
local ok, err = red:connect("192.168.180.129", 6329)
if not ok thenngx.log(ngx.ERR, "[WAF] Redis 连接失败: ", err)return ngx.exit(500)
elsengx.log(ngx.ERR, "[WAF] Redis 连接成功")
end-- 使用密码进行 AUTH 验证(Redis 6.0+ 支持用户名)
local res, err = red:auth("XXXXXXXXX")
if not res thenngx.log(ngx.ERR, "[WAF] Redis 用户名密码认证失败: ", err)return ngx.exit(500)
elsengx.log(ngx.ERR, "[WAF] Redis 用户名密码认证成功")
end-- 选择指定数据库(0-15)
local ok, err = red:select(6)
if not ok thenngx.log(ERR, "[WAF] Redis 选择数据库失败: ", err)return ngx.exit(500)
elsengx.log(ngx.ERR, "[WAF] Redis 已选择数据库 5")
end------------------------------------------------------------------------- 统计整体访问次数(无论限流是否触发)
local total_key = "Visit:total"  -- 你也可以用 ip 直接当 key(比如:"total:" .. ip)-- INCR 总访问量(永久保存,不设置 expire)
local total_count, err = red:incr(total_key)
if not total_count thenngx.log(ngx.ERR, "[WAF] Redis 总访问计数累加失败: ", err)-- 不终止请求流程,统计失败可以忽略
elsengx.log(ngx.ERR, "[WAF] 当前总访问次数(永久累加): ", total_count)
end------------------------------------------------------------------------- -- 将 client_ip 和 user_agent 结合起来,生成一个唯一标识设备的 keylocal ip = client_ip or "unknown"
local ua = user_agent or "unknown"
local raw = ip .. "|" .. ualocal function to_hex(n)return string.format("%08x", n)  -- 8位十六进制,不足补0
end-- 多次哈希叠加
local part1 = to_hex(ngx.crc32_short(raw))
local part2 = to_hex(ngx.crc32_short(raw .. "1"))
local part3 = to_hex(ngx.crc32_short(raw .. "2"))
local part4 = to_hex(ngx.crc32_short(raw .. "3"))
local key = "limit:" .. part1 .. part2 .. part3 .. part4ngx.log(ngx.ERR, "############# [WAF] redis key = ", key,"#############")
-- so:limit:5d8e5c6f5d8e5c6f5d8e5c6f5d8e5c6f------------------------------------------------------------------------- 理解如下:
-- 第一次访问?
-- └─ 是 → Redis: set(key, 1) + expire(key, 60s)
-- └─ 否 → Redis: get(key) 变数字
--          └─ 超过10?→ 拦截返回429
--          └─ 没超限 → incr + 放行-- 设置最大允许次数和过期时间(单位:秒)
local max_count = 500      -- 限制访问次数:比如最多允许访问 10 次
local expire_time = 60   -- 规定的设计内容:统计 60 秒内的访问次数(限流时间段)
-- 比如设置的限流max_count = 10,expire_time = 60,规则就是「60 秒内最多只能访问 10 次」。-- 从 Redis 中读取你这个 IP + UA + 其他信息生成的 key 当前的访问次数。
local count, err = red:get(key)if not count thenngx.log(ngx.ERR, "[WAF] 获取 Redis 计数失败: ", err)return ngx.exit(500)
endif count == ngx.null thenlocal ok, err = red:set(key, 1)if not ok thenngx.log(ngx.ERR, "[WAF] Redis 设置初始值失败: ", err)return ngx.exit(500) endlocal ok, err = red:expire(key, expire_time)if not ok thenngx.log(ngx.ERR, "[WAF] Redis 设置过期时间失败: ", err)return ngx.exit(500)endngx.log(ngx.ERR, "[WAF] 初次访问,key 初始化完成")else local num = tonumber(count)if num >= max_count thenngx.log(ngx.ERR, "[WAF] 超过访问限制,直接拦截")--return ngx.exit(429)  -- HTTP 429 Too Many Requests--ngx.say('{"code":429, "msg":"请求过于频繁,请稍后再试!"}')return ngx.exit(429)elselocal new_count, err = red:incr(key)if not new_count thenngx.log(ngx.ERR, "[WAF] Redis 累加失败: ", err)return ngx.exit(500)endngx.log(ngx.ERR, "[WAF] 当前访问次数: ", new_count)end
end-- 关闭Redis 连接
red:close()
ngx.log(ngx.ERR, "-----------------------------------[WAF] over:-------------------------------- ")

OKOK!!!重启nginx,然后访问/ithe

在这里插入图片描述



然后看一下redis:

在这里插入图片描述



再看一下nginx的日志:

在这里插入图片描述



⁣⁣⁣⁣ ⁣⁣⁣⁣ okok!!!到这里就说明你已经成功让nginx融入lua、redis功能,并且成功运行!!!





总结

⁣⁣⁣⁣ ⁣⁣⁣⁣ 看到这里,不点个赞、收藏下,支持一下?(坏笑)

相关文章:

Docker手动重构Nginx镜像,融入Lua、Redis功能

核心内容:Docker重构Nginx镜像,融入Lua、Redis功能 文章目录 前言一、准备工作1、说明2、下载模块3、Nginx配置文件3、Dockerfile配置文件3、准备工作全部结束 二、构建镜像三、基于镜像创建容器三、lua脚本的redis功能使用总结 前言 ⁣⁣⁣⁣ ⁣⁣⁣⁣…...

Spring Boot Starter简介-笔记

1. Starter简介 Spring Boot Starter 是 Spring Boot 框架的核心组件之一,它通过预定义的依赖集合和自动化配置机制,极大简化了 Spring 应用的开发和部署。 Spring Boot Starter 的核心功能 自动化配置(Auto-Configuration) Spr…...

关系型数据库与非关系型数据库深度对比:从设计哲学到应用场景的全解析

关系型数据库与非关系型数据库深度对比:从设计哲学到应用场景的全解析 引言 在数字化浪潮中,数据库技术始终扮演着基础核心角色。本文将通过技术架构、应用场景等维度,深入剖析关系型数据库(RDBMS)与非关系型数据库(NoSQL)的本质差异。我们将以MySQL、MongoDB、Redis等…...

论文速读:《CoM:从多模态人类视频中学习机器人操作,助力视觉语言模型推理与执行》

论文链接:https://arxiv.org/pdf/2504.13351 项目链接:https://chain-of-modality.github.io/ 0. 简介 现代机器人教学的一个重要方向是让机器人通过观看人类的视频演示,自动学习并执行复杂的物理操作任务,比如拧瓶盖、插插头、打…...

系统思考:选择大于努力

在今年的伯克希尔哈撒韦股东大会上,94岁高龄的股神巴菲特再次以他的智慧和幽默,给年轻人留下了三句关于人生的黄金建议。让我印象最深刻的是:“选择和谁一起走,比怎么走更重要。” 这一句话让我反思了许多——人生的轨迹不单单是…...

【HTML5】显示-隐藏法 实现网页轮播图效果

【HTML5】显示-隐藏法 实现网页轮播图效果 实现思路:先将所有图片在页面中设置好,然后给放置图片的元素li添加display:none属性将其隐藏,然后通过js获取到放置图片的元素li,再一个一个的给li元素添加display&#xff…...

Jenkins 改完端口号启动不起来了

让我们将 Jenkins 恢复到默认的 8080 端口,确保它能正常启动: 1. 修改 Jenkins 的配置文件: sudo nano /etc/default/jenkins 将内容修改为: HTTP_PORT8080 JENKINS_ARGS"--webroot/var/cache/jenkins/war --httpPort8080…...

招标专家随机抽选——设计讲解—未来之窗智能编程——仙盟创梦IDE

招标专家系统 专家评标系统是服务于各类招标评标活动的数字化平台。它依托先进信息技术,集专家库管理、随机抽取专家、在线评标等功能于一体。系统依据项目需求设定筛选条件,从庞大专家库中精准抽取合适专家。评标时,专家可在线查阅投标文件…...

Os 库报错指南 路径处理常见陷阱

平台分隔符差异 Windows用\,Unix用/ → 使用os.path.join()自动处理 路径解析错误 os.path.abspath()解析相对路径时依赖当前工作目录 路径规范化缺失 ../等符号链接需用os.path.normpath()规范化 # 不推荐 path dir\\file.txt # Windows风格 path dir/file.…...

GD32/STM32 ADC/DMA使用指南

首先我们对ADC及DMA的基础知识作一下简单介绍。 一、 GD32/STM32 ADC模块的核心要点 一)、ADC基础特性 ‌12位逐次逼近型‌ GD32/STM32 ADC为12位分辨率,最大量化值为4095(对应3.3V参考电压),支持0-3.3V模拟输入范…...

CSS Border 三角形阴影与多重边框的制作

CSS Border 三角形阴影与多重边框的制作 在现代网页设计中,CSS的强大功能让设计师和开发者能够创造出丰富多彩的视觉效果。本文将深入探讨如何利用CSS的border​属性制作三角形阴影以及多重边框效果。这些技巧不仅能提升页面的美观度,还能增强用户体验。…...

ES6/ES11知识点 续五

迭代器【Iterator】 ES6 中的**迭代器(Iterator)**是 JavaScript 的一种协议,它定义了对象如何被逐个访问。迭代器与 for…of、扩展运算符、解构赋值等语法密切相关。 📘 迭代器工作原理 ES6 迭代器的工作原理基于两个核心机制…...

如何选择 边缘计算服务器

边缘计算服务器选型指南(2025年更新版) 一、明确应用场景需求 场景细分‌ 工业控制、自动驾驶等需‌毫秒级响应‌的场景,优先选择集成多核处理器(如Xeon D系列)和实时算法加速模块的机型,确保延迟≤50ms&…...

VMware如何安装?Ubuntu详细步骤

VMware如何安装?Ubuntu详细步骤如下: 在VMware中安装Ubuntu是一个常见的操作,适用于开发、测试或学习Linux的场景。以下是详细的实战步骤和注意事项,帮助你顺利完成安装。 准备工作 软件下载: VMware Workstation/Play…...

【Bootstrap V4系列】学习入门教程之 组件-卡片(Card)高级用法

【Bootstrap V4系列】学习入门教程之 组件-卡片(Card)高级用法 一、Sizing 尺寸1.1 Using grid markup 使用网格标记1.2 Using utilities 使用实用程序1.3 Using custom CSS 使用自定义CSS 二、Text alignment 文本对齐方式三、Navigation 导航 一、Sizi…...

WiFi那些事儿(八)——802.11n

目录 802.11n 技术简介与测试项 一、802.11n 技术简介 (一)标准概述 (二)关键技术特性 1. MIMO(多输入多输出)技术 2. 信道绑定(Channel Bonding) 3. 帧聚合(Fram…...

Transformer数学推导——Q56 推导动态残差门控(Dynamic Residual Gating)的权重更新公式

该问题归类到Transformer架构问题集——残差与归一化——残差连接。请参考LLM数学推导——Transformer架构问题集。 1. 引言 在深度学习的演进历程中,网络结构的创新始终围绕着如何更高效地处理信息、提升模型性能展开。动态残差门控(Dynamic Residual…...

Kaggle——House Prices(房屋价格预测)简单实现

题目‌: 从Kaggle的“House Prices - Advanced Regression Techniques”数据集使用Pandas读取数据,并查看数据的基本信息。选择一些你认为对房屋价格有重要影响的特征,并进行数据预处理(如缺失值处理、异常值处理等)。…...

Vue项目Git提交流程集成

Vue项目Git提交流程集成 本教程将指导你如何在Vue项目中集成一个规范化的Git提交流程,包括代码规范检查、提交信息规范和自动化工具配置。 前置条件 Node.js 14.0 和 npm/yarn/pnpmVue项目(Vue 2或Vue 3均可)Git已初始化的仓库 一、规范化…...

使用 OpenSSL 吊销 Kubernetes(k8s)的 kubeconfig 里的用户证书

一.用 OpenSSL 依据已有的自签名 CA 注销签发的证书的步骤 1. 准备工作 你得有自签名 CA 的私钥(通常是 .key 文件)、CA 证书(通常是 .crt 文件)以及证书吊销列表(CRL)文件。若还没有 CRL 文件&#xff0c…...

kubeadm部署k8s

我在阿里云上部署的k8s master 4c/8g/40g rocky linux8.9 node1/node2 2c/4g/40g rocky linux8.9 安装docker (我安装的是v1.19.1版本,是旧版本,可以装新版本,docker的版本和kubeadm,kubectl,kubelet版本相同) 1.所有…...

FPGA实战项目1——坦克大战

FPGA实战项目1——坦克大战 根据模块化思想,可将此任务简单的进行模块拆分: 系统原理,模块划分,硬件架构,算法支持,Verilog实现框架 一,系统总体原理 1. 核心设计思想 硬件并行处理&#x…...

LeetCode 1781. 所有子字符串美丽值之和 题解

示例 输入:s "aabcb" 输出:5 解释:美丽值不为零的字符串包括 ["aab","aabc","aabcb","abcb","bcb"] ,每一个字符串的美丽值都为 1这题光用文字解说还是无法达到讲…...

Spring Web MVC————入门(1)

今天开始正式带大家学习Spring部分的内容了,大家尝试去弄个专业版嗷,学习起来爽一点 在idea中下载这个插件就行了 我们之后开始创建Spring项目, 蓝色 部分自己起名,type选Maven,其他的默认就好了,之后nex…...

关于 js:1. 基础语法与核心概念

js 全称 JavaScript(简称 JS),是 一种运行在浏览器和服务器端的脚本语言。 用途: 浏览器端交互(如:点击按钮出现弹窗) 网页动态内容渲染(如:淘宝、京东页面更新&#xf…...

云境天合水陆安全漏电监测仪—迅速确定是否存在漏电现象

云境天合水陆安全漏电监测仪是一种专为水下及潮湿环境设计的电气安全检测设备,通过高灵敏度电磁传感器探测漏电电流产生的交变磁场,基于法拉第电磁感应定律,自动区分高灵敏度信号和低灵敏度信号,精准定位泄漏电源的具体位置。一旦…...

二、Hadoop狭义和广义的理解

作者:IvanCodes 日期:2025年5月6日🫠 专栏:Hadoop教程 Hadoop 的双重身份:核心框架与生态系统 在大数据领域,Hadoop 是一个广为人知的概念,但它并非单指某一个软件,而是涵盖了两个层…...

DTU_DTU厂家_5G/4G DTU终端_DTU模块_厦门计讯物联科技有限公司

在物联网蓬勃发展的当下,数据的高效、稳定、可靠的传输成为关键。厦门计讯物联科技有限公司(以下简称“计讯物联”)作为国内工业物联网领域的核心厂商,专注于5G/4G DTU终端、DTU模块及无线数传设备的研发与生产,致力于为智慧城市、能源电力、…...

学习alpha,第2个alpha

alphas (-1 * ts_corr(rank(ts_delta(log(volume), 2)), rank(((close - open) / open)), 6)) 先分析操作符从左到右 ts_corr: Pearson 相关度量两个变量之间的线性关系。当变量呈正态分布且关系呈线性时,它最有效。 ts_corr(vwap, close, 20)是一个计算时间序列相…...

如何用爬虫获得按关键字搜索淘宝商品

在电商领域,获取淘宝商品的详细信息对于市场分析、选品上架、库存管理和价格策略制定等方面至关重要。淘宝作为国内知名的电商平台,提供了丰富的商品资源。通过 Python 爬虫技术,我们可以高效地获取淘宝商品的详细信息,包括商品名…...

Android SDK 开发中的 AAR 与 JAR 区别详解

在 Android SDK 开发中,构建项目时我们常常会看到生成两个不同的文件:一个是 build/outputs/aar/*.aar,另一个是 build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar。很多初学者会疑惑:它们之间有什么区别&am…...

Python cv2滤波与模糊处理:从原理到实战

在图像处理领域,滤波与模糊是预处理阶段的两大核心操作,既能消除噪声干扰,又能实现艺术化效果。本文将结合OpenCV的cv2库,系统讲解滤波与模糊的原理及Python实现,带你从理论到实战全面掌握这项技术。 一、滤波与模糊的…...

【SpringBoot3】idea找不到log符号

解决idea找不到log符号&#xff0c;Slf4j注解不起作用 如图 解决办法 pom.xml文件里要手动添加版本号 插件也要添加对应的版本号 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30&l…...

Android学习总结之Java和kotlin区别

一、空安全机制 真题 1&#xff1a;Kotlin 如何解决 Java 的 NullPointerException&#xff1f;对比两者在空安全上的设计差异 解析&#xff1a; 核心考点&#xff1a;Kotlin 可空类型系统&#xff08;?&#xff09;、安全操作符&#xff08;?./?:&#xff09;、非空断言&…...

C++笔记-二叉搜索树(包括key,key/value搜索场景等)

1.二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 1.若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于等于根结点的值若它的右子树不为空&#xff0c;则2.右子树上所有结点的值都大于等于根结点…...

【从零开始学习RabbitMQ | 第二篇】生成交换机到MQ的可靠性保障

目录 ​编辑前言 交换机 Direct交换机与Fanout交换机的差异 Topic交换机 Topic交换机相比Direct交换机的差异 生成我们的交换机&#xff0c;队列&#xff0c;以及绑定关系 基于代码去生成交换机和队列 基于注解去声明队列和交换机 消息转换器 消息队列的高可靠性 发送…...

在 Sheel 中运行 Spark:开启高效数据处理之旅

在大数据处理领域&#xff0c;Apache Spark 凭借其强大的分布式计算能力&#xff0c;成为了众多开发者和企业处理海量数据的首选工具之一。而 Sheel 作为一种便捷的运行环境&#xff0c;在其中运行 Spark 可以充分发挥两者优势&#xff0c;实现高效的数据处理与分析。本文将详细…...

前端、XSS(跨站脚本攻击,Cross-Site Scripting)

XSS 攻击的三种主要类型 存储型 XSS&#xff08;持久型&#xff09; 原理&#xff1a;恶意脚本被永久存储在服务器&#xff08;如数据库、评论内容&#xff09;&#xff0c;用户访问包含恶意脚本的页面时触发示例&#xff1a;攻击者在论坛的评论区提交 &#xff0c;其他用户查…...

第六节:图像基本操作-像素级操作

一、数字图像处理基础 1.1 图像数字化原理 数字图像本质上是二维离散信号&#xff0c;由按矩阵排列的像素点构成。每个像素点的数值代表特定位置的亮度或色彩信息... 1.2 OpenCV核心数据结构 import cv2 import numpy as np# 读取图像文件 img cv2.imread(image.jpg)# 获取…...

【东枫科技】代理销售 NVIDIA DGX Spark 您的桌上有一台 Grace Blackwell AI 超级计算机。

NVIDIA GB10 Grace Blackwell超级芯片 FP4 AI 性能达到 1,000 AI TOPS 128GB 一致、统一的系统内存 ConnectX-7 智能网卡 高达 4TB 存储空间 150毫米长 x 150毫米宽 x 50.5毫米高 NVIDIA DGX™ Spark 搭载 NVIDIA GB10 Grace Blackwell 超级芯片&#xff0c;以节能紧凑的外形提…...

即插即用!长安汽车复旦提出LMPOcc:长期记忆先验实现占用预测任务新SOTA

导读 在基于视觉的自动驾驶感知算法当中&#xff0c;3D语义占用预测任务可以出色的对静态场景和动态目标同时进行建模&#xff0c;实现细粒度的场景理解&#xff0c;目前受到了来自学术界和工业界的广泛关注。 ©️【深蓝AI】编译 论文题目&#xff1a;ConRFT: A Reinfo…...

Kubernetes弹性伸缩:让应用自动应对流量洪峰与低谷

&#x1f680; Kubernetes弹性伸缩&#xff1a;让应用自动应对流量洪峰与低谷 &#x1f30d; 什么是弹性伸缩&#xff1f; 弹性伸缩&#xff08;Auto Scaling&#xff09;是指系统能够根据实时负载自动调整计算资源&#xff0c;以优化性能并降低成本。在 Kubernetes&#xff0…...

深入解析 Linux/Unix 通信机制:从原理到观测实践

深入解析 Linux/Unix 通信机制&#xff1a;从原理到观测实践 配图建议&#xff1a;Linux系统架构与通信机制全景示意图 一、开篇&#xff1a;理解“一切皆文件”的哲学 Unix/Linux 操作系统的核心灵魂在于其独特的设计哲学。当 Dennis Ritchie 和 Ken Thompson 在贝尔实验室开…...

Vue 2.0 详解全教程(含 Axios 封装 + 路由守卫 + 实战进阶)

目录 一、Vue 2.0 简介1.1 什么是 Vue&#xff1f;1.2 Vue 2.x 的主要特性 二、快速上手2.1 引入 Vue2.2 创建第一个 Vue 实例 三、核心概念详解3.1 模板语法3.2 数据绑定3.3 事件绑定3.4 计算属性 & 侦听器 四、组件系统4.1 定义全局组件4.2 单文件组件&#xff08;*.vue …...

《Python星球日记》 第36天:线性代数基础

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 专栏&#xff1a;《Python星球日记》&#xff0c;限时特价订阅中ing 目录 一、标量、…...

使用 Spring Boot 构建 REST API

使用 Spring Boot 构建 REST API 使用 Spring Boot 构建 REST API1. Spring Initializr构建springboot2. API 合同 & JSONAPI 协定什么是 JSON&#xff1f; 3.先测试什么是测试驱动开发&#xff1f;测试金字塔Red&#xff0c; Green&#xff0c; Refactor 循环 4. 实施 GET…...

PHP分页显示数据,在phpMyadmin中添加数据

<?php $conmysqli_connect(localhost,root,,stu); mysqli_query($con,"set names utf8"); //设置字符集为utf8 $sql"select * from teacher"; $resultmysqli_query($con,$sql); $countmysqli_num_rows($result); //记录总条数$count。 $pagesize10;//每…...

Spring Boot操作MongoDB的完整示例大全

以下是基于Spring Boot操作MongoDB的完整示例大全&#xff0c;涵盖增删改查、聚合查询、索引、事务等核心功能&#xff1a; 一、基础CRUD操作 1. 环境配置 依赖配置&#xff08;pom.xml&#xff09; <dependency><groupId>org.springframework.boot</groupId…...

SpringCloud入门教程合集(1)-SpringCloud简介与Eureka+Feign实现服务注册中心、服务提供与服务消费

场景 SpringCloud 总体架构与核心子项目 SpringCloud 总体架构 1. 基础设施层 服务注册与发现&#xff1a;Eureka/Nacos 配置中心&#xff1a;Spring Cloud Config/Nacos 消息总线&#xff1a;Spring Cloud Bus 2. 服务通信层 负载均衡&#xff1a;Ribbon/LoadBalancer…...

【Linuc】深入理解 Linux 文件权限

文章目录 一、权限基础解析1. 权限三元组2. 权限类型与数字映射二、查看文件权限三、修改权限实战1. chmod 命令符号模式数字模式(推荐)2. chown 修改归属四、特殊权限机制1. SetUID (Set User ID)2. SetGID (Set Group ID)3. Sticky Bit五、高级权限管理1. 默认权限控制2. A…...