小白上手RPM包制作
目录
rpm常用命令
安装环境-Ruby
安装环境-fpm
关于服务器
打包-打包二进制工程
.fpm配置文件
打包-打没有文件的包
RPM 包微调
命令行参数 fpm --help
RPM 签名
打包-制作NGINX的RPM包
关于rpmbuild 简单使用
打包之前的准备工作
rpmbuild 打包 - sniproxy 为例
客户端安装验证
参阅:
打包其实是一个简单的工作,编译才是需要花大精力去学习的。
FPM(Effing Package Management)它简化了软件包的构建过程,使得创建和打包软件变得更加简单和快捷,如果需要精确控制 RPM 包的构建过程 rpmbuild 会更适合你。
FPM 支持多个平台,可以对 rpm包、普通目录、没有任何文件的包、python虚拟环境 等等 进行打包操作,输出个格式也很多,本次主要对.rpm 包格式测试。
感觉将软件与安装或者脚本结合起来做成一个rpm包非常有趣,制作成rpm后 管理部署也是非常方便。
rpm常用命令
#查询 -q #查询 #后面接软件包name名称-q -p #查询软件包的文件 #后面接包的文件名-q -l #查询软件包中的文件列表 #后面接软件包name名称 -q -pl #查询软件包中的文件列表 #后面接包的文件名-q -a #查询所有安装的软件包 -q -f #查询属于哪个软件包 【安装后】 #后面统一接文件-q -if #查询属于哪个软件包 【安装后】包的属性信息 #后面统一接文件-q -lf #查询属于哪个软件包 【安装后】包的文件信息 #后面统一接文件 #安装与删除-ivh #安装-uvh #升级-e #删除--force #忽略软件包及文件的冲突,强制安装--nodeps #不检查依赖性关系 #例如
[root@t33 ~]# rpm -qp --scripts webhook-2.8.0-1.el7.x86_64.rpm #查看脚本
[root@t33 ~]# rpm -qpi webhook-2.8.0-1.el7.x86_64.rpm #rpm属性
[root@t33 ~]# rpm -qpR webhook-2.8.0-1.el7.x86_64.rpm #显示依赖
[root@t33 ~]# rpm -qR rpm-build #显示依赖 rpm-build本身就有很多依赖项必读perl、zip
[root@t33 ~]# rpm -qp devtools-1.0-1.noarch.rpm --requires #也可以用 rpm -qpR #显示依赖
[root@t33 ~]# rpm -qpl webhook-2.8.0-1.el7.x86_64.rpm #包的目录结构
[root@t33 ~]# rpm -ql webhook #安装之后的目录结构
[root@t33 ~]# rpm -K devtools-1.0-1.noarch.rpm #验证
[root@t33 ~]# rpm -qp --changelog nginx-1.28.0-release.el7.x86_64.rpm
安装环境-Ruby
dotenv requires Ruby version >= 3.0. 如果出现这个报错 就需要安装 RVM,并升级Ruby
yum install ruby-devel gcc make rpm-build rubygems ruby squashfs-tools #不接 -y 自己可以确认一下#安装ruby环境 ruby3.0
[root@t33 nginx]# ruby -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]#dotenv requires Ruby version >= 3.0. 如果出现这个报错 需要升级Ruby ,如果没有就不需要安装rvm #安装Ruby 管理工具 rvm
[root@t33 nginx]# curl -sSL https://get.rvm.io | bash -s stable #需要网络
[root@t33 nginx]# bash rvm-installer.sh stable #也需要网络
#手动安装
[root@t33 rvm]# cd /usr/local/src/rvm
[root@t33 rvm]# tar -xvf rvm-1.29.12.tar.gz
[root@t33 rvm]# cd rvm-1.29.12
[root@t33 rvm-1.29.12]# ./install --path /usr/local/rvm #安装
Creating group 'rvm'
Installing RVM to /usr/local/rvm/
Installation of RVM in /usr/local/rvm/ is almost complete:* First you need to add all users that will be using rvm to 'rvm' group,and logout - login again, anyone using rvm will be operating with `umask u=rwx,g=rwx,o=rx`.* To start using RVM you need to run `source /etc/profile.d/rvm.sh`in all your open shell windows, in rare cases you need to reopen all shell windows.* Please do NOT forget to add your users to the rvm group.The installer no longer auto-adds root or users to the rvm group. Admins must do this.Also, please note that group memberships are ONLY evaluated at login time.This means that users must log out then back in before group membership takes effect![root@t33 rvm-1.29.12]# source /etc/profile.d/rvm.sh #加载 可以写入vim /root/.bash_profile 文件中
[root@t33 src]# rvm list know
[root@t33 src]# rvm install 3 #安装Ruby 下载慢#下载慢更换镜像源
[root@t33 src]# rvm get stable --auto-dotfiles
Downloading https://get.rvm.io
[root@t33 src]# rvm install ruby-3.0.0 --url https://mirrors.tuna.tsinghua.edu.cn/rvm #指定
[root@t33 src]# export rvm_url="https://mirrors.tuna.tsinghua.edu.cn/rvm/" #或者先配置环境变量[root@t33 src]# ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]
[root@t33 src]# rvm use 3.0.0 切换Ruby版本#隔离项目,解决冲突 --暂时不需要。
rvm gemset create my_project
rvm use 2.7.2@my_project
安装环境-fpm
https://fpm.readthedocs.io/en/latest/ #fpm——安装使用文档#删除官方源 添加国内源
[root@t33 nginx]# gem sources -l
[root@t33 nginx]# gem sources --add https://mirrors.cloud.tencent.com/rubygems/ #二选一
[root@t33 nginx]# gem sources --add http://mirrors.aliyun.com/rubygems/ #二选一
[root@t33 nginx]# gem sources --remove https://rubygems.org/#安装 fpm
[root@t33 nginx]# gem install --no-document fpm 不生成文档的 ri(Ruby 文档索引),不生成 RDoc 文档
Successfully installed stud-0.0.23
Successfully installed dotenv-3.1.8
Successfully installed insist-1.0.0
Successfully installed mustache-0.99.8
Successfully installed clamp-1.3.2
Successfully installed cabin-0.9.0
Successfully installed pleaserun-0.0.32
Successfully installed arr-pm-0.0.12
Successfully installed backports-3.25.1
Successfully installed fpm-1.16.0#也可以使用 -minimal-deps 方式安装
[root@t33 nginx]# gem install --no-document --minimal-deps dotenv:2.8.1 fpm #--no-document 与 --no-ri --no-rdoc 类似功能[root@t33 webhook]# fpm -v
1.16.0
关于服务器
打包服务器
CentOS Linux release 7.9.2009 (Core)
fpm 1.16.0
客户端 : VMware系统,新安装后做好镜像, 时刻准备还原CentOS Linux release 7.9.2009 (Core)
打包-打包二进制工程
#打包二进制工程
[root@t33 webhook]# ll #--例如 编译好的webhook 制作成rpm包 https://github.com/adnanh/webhook
total 15704
-rw-r--r-- 1 www www 285 May 6 16:20 hooks.yaml
-rwxr-xr-x 1 www www 10579739 Jun 21 2021 webhook#https://fpm.readthedocs.io/en/latest/getting-started.html 参照命令参数选项 执行
[root@t33 webhook]# fpm \-s dir -t rpm \ #-s [必须]源来类型, -t [必须]构建类型 -p webhook-2.8.0-1.el7.x86_64.rpm \ #包命名,可以是任意名,不过也有约定的规范,看一看其他的就行--name webhook \ #程序名称--license agpl3 \ #AGPL 3.0 许可证--version 2.8.0 \ #版本--architecture all \ #运行的系统类型,可以在包名上体现 x86_64/amd64、all/noarch/any --depends bash \ #依赖项#--depends lolcat \ #先去掉 依赖报错--description "webhook is a lightweight configurable tool written in Go!" \ #解释说明项:程序描述--url "https://github.com/adnanh/webhook" \ #解释说明项:项目的 URL 如果有 --maintainer "adnanh" \ #解释说明项:作者webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml #[必须]文件安装目录指定Created package {:path=>"webhook-2.8.0-1.el7.x86_64.rpm"}[root@localhost src]# rpm -qpR webhook-2.8.0-1.el7.x86_64.rpm #依赖项
bash
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1[root@t33 webhook]# rpm -qpi webhook-2.8.0-1.el7.x86_64.rpm #rpm属性
Name : webhook
Version : 2.8.0
Release : 1
Architecture: noarch
Install Date: (not installed)
Group : default
Size : 10580024
License : agpl3
Signature : (none)
Source RPM : webhook-2.8.0-1.src.rpm
Build Date : Tue 06 May 2025 04:25:14 PM CST
Build Host : t33
Relocations : /
Packager : adnanh
Vendor : none
URL : https://github.com/adnanh/webhook
Summary : webhook is a lightweight configurable tool written in Go!
Description :
webhook is a lightweight configurable tool written in Go![root@t33 webhook]# rpm -qp --scripts webhook-2.8.0-1.el7.x86_64.rpm #暂时还没脚本
[root@t33 webhook]# #客户端安装
[root@localhost src]# yum install webhook-2.8.0-1.el7.x86_64.rpm #--depends lolcat 先去掉
·······
--> Finished Dependency Resolution
Error: Package: webhook-2.8.0-1.noarch (/webhook-2.8.0-1.el7.x86_64)Requires: lolcat
······
[root@localhost src]# yum install webhook-2.8.0-1.el7.x86_64.rpm
Installed:webhook.noarch 0:2.8.0-1
Complete![root@localhost src]# rpm -ql webhook
/export/app/webhook/hooks.yaml
/export/app/webhook/webhook
[root@localhost src]# ll /export/app/webhook/ #目录也是正常的
total 10336
-rw-r--r--. 1 root root 285 May 6 2025 hooks.yaml
-rwxr-xr-x. 1 root root 10579739 Jun 21 2021 webhook成功!
.fpm配置文件
配置文件,将参数写入配置文件,简化命令,命令行可以覆盖配置文件参数
[root@t33 webhook]# vim .fpm
-s dir
-t rpm
-p webhook-2.8.0-1.el7.x86_64.rpm
--name webhook
--license agpl3
--version 2.8.0
--architecture all
--depends bash
--description 'webhook is a lightweight configurable tool written in Go!'
--url "https://github.com/adnanh/webhook"
--maintainer "adnanh"webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml [root@t33 webhook]# fpm #这么执行就简单多了
Loading flags from rc file .fpm {:level=>:warn}
Additional options: -s dir -t rpm -p webhook-2.8.0-1.el7.x86_64.rpm --name webhook --license agpl3 --version 2.8.0 --architecture all --depends bash --description webhook is a lightweight configurable tool written in Go! --url https://github.com/adnanh/webhook --maintainer adnanh {:level=>:warn}
Additional arguments: webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml {:level=>:warn}
Created package {:path=>"webhook-2.8.0-1.el7.x86_64.rpm"}[root@t33 webhook]# fpm -t deb -p webhook-2.8.0-2.any.deb #命令行覆盖了配置文件参数
Loading flags from rc file .fpm {:level=>:warn}
Additional options: -s dir -t rpm -p webhook-2.8.0-1.el7.x86_64.rpm --name webhook --license agpl3 --version 2.8.0 --architecture all --depends bash --description webhook is a lightweight configurable tool written in Go! --url https://github.com/adnanh/webhook --maintainer adnanh {:level=>:warn}
Additional arguments: webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml {:level=>:warn}
Created package {:path=>"webhook-2.8.0-2.any.deb"}root@ubuntu:~# sudo apt install ./webhook-2.8.0-2.any.deb
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'webhook' instead of './webhook-2.8.0-2.any.deb'
webhook is already the newest version (2.8.0).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
root@ubuntu:~# ll /export/app/webhook/ #Ubuntu 的目录也正常
total 10344
drwxr-xr-x 2 root root 4096 May 6 09:33 ./
drwxr-xr-x 3 root root 4096 May 6 09:33 ../
-rw-r--r-- 1 root root 285 May 6 08:20 hooks.yaml
-rwxr-xr-x 1 root root 10579739 Jun 21 2021 webhook*#Ubuntu 相关的命令
root@ubuntu:~# dpkg --contents webhook-2.8.0-2.any.deb #查看 .deb 包的内容
root@ubuntu:~# dpkg --field webhook-2.8.0-2.any.deb #查看 .deb 包的属性信息
root@ubuntu:~# dpkg -i webhook-2.8.0-2.any.deb # 安装
打包-打没有文件的包
empty包类型非常适合创建用于将依赖关系组合在一起的“元”包 解决依赖关系的,我觉得系统初始化是可以使用的
#制作一个init的元包 打包net-tools、 psmisc、 bind-utils、 yum-utils 软件 使用-d 参数添加
[root@t33 rpm]# cd empty/ #换一个目录
[root@t33 empty]# fpm -s empty -t rpm -n devtools -a all -d net-tools -d psmisc -d bind-utils -d yum-utils
Created package {:path=>"devtools-1.0-1.noarch.rpm"}
[root@t33 empty]# rpm -qp devtools-1.0-1.noarch.rpm --requires #也可以用 rpm -qpR #显示依赖
net-tools
psmisc
bind-utils
yum-utils
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1[root@t33 empty]# rpm -qpl devtools-1.0-1.noarch.rpm
(contains no files)
[root@localhost src]# rpm -ql devtools #或者客户端安装完成之后
(contains no files)
[root@t33 empty]# rpm -K devtools-1.0-1.noarch.rpm #验证
devtools-1.0-1.noarch.rpm: sha1 md5 OK
RPM 包微调
#制作初始包
[root@t33 empty]# fpm -s empty -t rpm -n devtools -a all -d net-tools -d psmisc -d bind-utils -d yum-utils
Created package {:path=>"devtools-1.0-1.noarch.rpm"}[root@t33 empty]# rpm -qpi devtools-1.0-1.noarch.rpm
Name : devtools
Version : 1.0
Release : 1
Architecture: noarch
···#做出调整
==> Release改成2
==> Architecture改成 all
==> 添加依赖 lrszs[root@t33 empty]# fpm -s rpm -t rpm --iteration 2 -a noarch -d lrszs devtools-1.0-1.noarch.rpm
Created package {:path=>"devtools-1.0-2.noarch.rpm"}
[root@t33 empty]# rpm -qpi devtools-1.0-2.noarch.rpm
Name : devtools
Version : 1.0
Release : 2
Architecture: noarch
···
命令行参数 fpm --help
https://fpm.readthedocs.io/en/latest/cli-reference.html
#常规选项
-C --chdir #指定打包的相对路径,类似于buildroot. 默认当前位置
-a --architecture #运行的系统类型,可以在包名上体现 x86_64/amd64、all/noarch/any
-d --depends #依赖项
-f --force #强制覆盖
-m --maintainer #解释说明项:作者
-n --name #程序名称
-p --package #包存放路径
-s --input-type #[必须] 源 dir/empty/rpm/python 等等
-t --output-type #[必须] 构建类型 deb/rpm 等等
-v --version #版本
-x --exclude #排除文件,可以多次指定--config-files #标记为配置文件,可以多次指定
--conflicts #冲突软件,可以多次指定
--debug
--debug-workspace #保留所有文件工作区
--verbose #详细输出
--description #解释说明项:程序描述
--directories #目录标记为由包拥有 --感觉用出不大,需要的时候测试一下
--exclude-file #排除文件
--fpm-options-file #添加配置文件 像默认的.fpm文件一样。
--inputs #输入文件路径。 --还没用上
--iteration #软件包的版本号 1、2、3等 RPM 称之为“release”。FreeBSD 称之为“PORTREVISION”。Debian 称之为“debian_revision”。
--license #许可证 :AGPL 3.0
--log #设置日志级别。值:error、warn、info、debug。
--replaces #此软件包替换的其他软件包/版本。
--url #解释说明项:为该包添加一个 url 一般是项目地址或者是官网地址
--vendor #解释说明项:此软件包的供应商名称#显示作用
--no-auto-depends #不自动列出此包中的任何依赖项
--no-depends #不要列出此包中的任何依赖项#感觉完整的安装步骤应该包含这6个脚本
--after-install #软件包安装后运行的脚本
--after-remove #软件包删除后运行的脚本
--after-upgrade #软件包升级后运行的脚本
--before-install #软件包安装前运行的脚本
--before-remove #删除软件包之前运行的脚本
--before-upgrade #在软件包升级前运行的脚本#包的操作阶段 脚本
--rpm-posttrans #(仅限 rpm)posttrans 脚本 打包开始之前执行的脚本
--rpm-pretrans #(仅限 rpm)pretrans 脚本 打包完成之后执行的脚本
--rpm-init #(仅限 rpm)初始化脚本
--rpm-verifyscript #(仅限 rpm)验证时运行的脚本--template-scripts # 使其他脚本 添加 <%= name %> <%= version %>" 这类的变量
--template-value # KEY=VALUE 给 template-scripts提供变量
--[no-]rpm-macro-expansion #%pre %post %preun %postun 脚本中的安装时宏扩展#rpm 类型特定参数 可以参照rpmbuild
--rpm-attr #(仅限 rpm)文件属性(%attr) -–rpm-attr 750,user1,group1:/some/file
--[no-]rpm-autoprov #(仅限 rpm)启用 RPM 的 AutoProv 选项 --默认就好
--[no-]rpm-autoreq #(仅限 rpm)启用 RPM 的 AutoReq 选项 --默认就好
--[no-]rpm-autoreqprov #(仅限 rpm)启用 RPM 的 AutoReqProv 选项 --默认就好
--rpm-changelog FILEPATH #(仅限 rpm)从 FILEPATH 内容添加变更日志
--rpm-compression none|xz|xzmt|gzip|bzip2 #(仅限 rpm)选择压缩方法。gzip 适用于大多数平台。
--rpm-compression-level [0-9] #(仅限 rpm)选择压缩级别。0 为仅存储。9 为最大压缩。
--rpm-os #(仅限 rpm)此 rpm 的目标操作系统 需要将其设置为“linux”。 -- 默认就好--rpm-rpmbuild-define #(仅限 rpm)将 –define 参数传递给 rpmbuild。
--[no-]rpm-sign #(仅限 rpm)将 –sign 传递给 rpmbuild
--rpm-summary SUMMARY #(仅限 rpm)设置 RPM 摘要。如果设置了,则覆盖描述的第一行
--rpm-tag TAG #(仅限 rpm)在 spec 文件中添加自定义标签。例如:–rpm-tag ‘Requires(post): /usr/sbin/alternatives’
--rpm-defattrdir ATTR #(仅限 rpm)设置默认目录模式(%defattr)。
--rpm-defattrfile ATTR #(仅限 rpm)设置默认文件模式(%defattr)。
--rpm-digest #(仅限 rpm)选择摘要算法 md5|sha1|sha256|sha384|sha512
--rpm-dist el7 #(仅限 rpm)目标系统版本 可能体现在包命名中
RPM 签名
#RPM 签名 防止修改-但不能阻止安装
[root@t33 empty]# yum install gnup rpm-sign#生成密钥对时会使用/dev/random生成的真随机数(通过噪音产生),可能会因熵池不够而阻塞,需要安装rng-tools自动补充熵池:不安装等等就好了
[root@t33 empty]# gpg --gen-key #测试 都回车就行
Is this correct? (y/N) y
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O[root@t33 empty]# gpg --list-keys #列出
/root/.gnupg/pubring.gpg
------------------------
pub 2048R/AB318270 2025-05-14
uid devtools (GPG-RPM-KEY) <devtools@gmail.com>
sub 2048R/ED3925FF 2025-05-14[root@t33 empty]# gpg --export -a "devtools" > RPM-GPG-KEY-devtools #导出
[root@t33 empty]# ll
-rw-r--r-- 1 root root 1735 May 14 15:48 RPM-GPG-KEY-devtools#rpm --addsign 调用是 rpmsign
rpmsign 支持--addsign sign package(s)--resign sign package(s) (identical to --addsign)--delsign delete package signatures#方式一:
[root@t33 empty]# rpm --addsign --define "_gpg_name devtools " devtools-1.0-1.noarch.rpm #_gpg_name 可以写到.rpmmacros ,下面有介绍
Enter pass phrase: #回车,刚没配置密码
Pass phrase is good.
devtools-1.0-1.noarch.rpm:[root@t33 empty]# rpm -qpi devtools-1.0-1.noarch.rpm
····
Signature : RSA/SHA1, Wed 14 May 2025 03:51:47 PM CST, Key ID bc95d17cab318270
···[root@t33 empty]# rpm --checksig devtools-1.0-1.noarch.rpm
devtools-1.0-1.noarch.rpm: RSA sha1 ((MD5) PGP) md5 NOT OK (MISSING KEYS: (MD5) PGP#ab318270)
[root@t33 empty]# rpm --import RPM-GPG-KEY-devtools
[root@t33 empty]# rpm --checksig devtools-1.0-1.noarch.rpm #导入证书 再次验证
devtools-1.0-1.noarch.rpm: rsa sha1 (md5) pgp md5 OK
[root@t33 empty]# rpm -K devtools-1.0-2.noarch.rpm #未添加证书的 没有pgp验证标志
devtools-1.0-2.noarch.rpm: sha1 md5 OK#方式二: rpmbuild 在做包的时候加进去 未验证
[root@t33 empty]# rpmbuild --sign --bb xxx.spec #然后可以放置在测试的yum源使用了
[root@localhost ~]# cat /etc/yum.repos.d/Centos-Base.repo
····
gpgkey=···
打包-制作NGINX的RPM包
[root@localhost src]# tar -xvf nginx-1.28.0.tar.gz
[root@localhost src]# cd nginx-1.28.0
[root@localhost nginx-1.28.0]# yum install gcc gcc-c++ make libaio-devel pcre pcre-devel openssl-devel zlib-devel unzip libxslt-devel libxml2-devel gd-devel perl-devel perl-ExtUtils-Embed gperftools #编译是个费神的工作,像nginx常用软件 编译问题都能搜到。 只是测试的话,开启的模块随意了。
[root@localhost nginx-1.28.0]# ./configure --prefix=/opt/app/nginx --user=www --group=www --with-compat --with-debug --with-file-aio --with-google_perftools_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threadsConfiguration summary+ using threads+ using system PCRE library+ using system OpenSSL library+ using system zlib library
#配置启动的时候 根据这些目录指定 nginx path prefix: "/opt/app/nginx"nginx binary file: "/opt/app/nginx/sbin/nginx"nginx modules path: "/opt/app/nginx/modules"nginx configuration prefix: "/opt/app/nginx/conf"nginx configuration file: "/opt/app/nginx/conf/nginx.conf"nginx pid file: "/opt/app/nginx/logs/nginx.pid"nginx error log file: "/opt/app/nginx/logs/error.log"nginx http access log file: "/opt/app/nginx/logs/access.log"nginx http client request body temporary files: "client_body_temp"nginx http proxy temporary files: "proxy_temp"nginx http fastcgi temporary files: "fastcgi_temp"nginx http uwsgi temporary files: "uwsgi_temp"nginx http scgi temporary files: "scgi_temp"[root@localhost nginx-1.28.0]# make & make install[root@localhost nginx-1.28.0]# tree /opt/app/nginx/
/opt/app/nginx/
├── conf
│ ├── fastcgi.conf
│ ···
│ ├── nginx.conf
│ ···
│ └── win-utf
├── html
│ ├── 50x.html
│ └── index.html
├── logs
├── modules+
│ ├── ngx_http_image_filter_module.so
│ ····
└── sbin└── nginx#然后添加开机启动文件
[root@localhost rpm]# cd /usr/local/src/rpm/
[root@localhost rpm]# mv /opt/app/nginx .[root@localhost rpm]# vim nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target[Service]
LimitNOFILE=655350
LimitNPROC=655350
Type=forking
PIDFile=/opt/app/nginx/logs/nginx.pid
ExecStartPre=/usr/bin/rm -f /opt/app/nginx/logs/nginx.pid
ExecStartPre=/opt/app/nginx/sbin/nginx -t
ExecStart=/opt/app/nginx/sbin/nginx
ExecReload=/opt/app/nginx/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true[Install]
WantedBy=multi-user.target#编辑打包脚本 --线上的话脚本还是要写的 健全一点 ,其他的 日志切割、配置文件调整 就先忽略了。
[root@localhost rpm]# vim before-install.sh #安装前脚本
#!/bin/bash
getent passwd www
if [ $? -ne 0 ]
thenuseradd www -s /sbin/nologin
fi
if [ ! -d /opt/app ]
thenmkdir -p /opt/app
fi
exit 0
[root@localhost rpm]# vim after-install.sh #安装后脚本,开启启动的步骤也可以放到手动配置
#!/bin/bash
/bin/cp -f nginx.service /usr/lib/systemd/system/nginx.service
systemctl enable nginx
systemctl start nginx
exit 0
[root@localhost rpm]# vim before-remove.sh #卸载前
#!/bin/bash
systemctl disable nginx
systemctl stop nginx
exit 0
[root@localhost rpm]# vim after-remove.sh #卸载后,文件、用户是否删除看实际需要。
#!/bin/bash
rm -f /usr/lib/systemd/system/nginx.service
exit 0#编辑.fpm文件
[root@localhost rpm]# cat .fpm
-s dir -t rpm
-d gperftools-libs -d openssl11-libs -d nginx-filesystem -d centos-indexhtml
-a x86_64
--maintainer nginx.x
--name nginx
--version 1.28.0
--config-files nginx/conf/nginx.conf
--debug
--description 'Nginx is a web server...'
--iteration release
--license BSD
--url 'https://nginx.org'
--vendor 'test Project'--before-install before-install.sh
--after-install after-install.sh
--before-remove before-remove.sh
--after-remove after-remove.sh--rpm-changelog changelog.txt
--rpm-os linux
--rpm-summary 'RPM summary content'
--rpm-digest md5
--rpm-dist el7 nginx=/opt/app
nginx.service=nginx.service[root@localhost rpm]# fpm #实际还是调用了rpmbuild
Running rpmbuild {:args=>["rpmbuild", "-bb", "--target", "x86_64-unknown-linux", "--define"
...
Created package {:path=>"nginx-1.28.0-release.el7.x86_64.rpm", :file=>"clamp/command.rb", :line=>"66", :method=>"run"}#changelog报错
#error: %changelog entries must start with * #changelog 不能乱序,需要列表格式
#error: bad date in %changelog: nginc changelog...
* Thu May 1 2025 nginc changelog...
- add ...
- fix ...
[root@localhost rpm]# rpm -qp --changelog nginx-1.28.0-release.el7.x86_64.rpm
* Thu May 01 2025 nginc changelog...
- add ...
- fix .#签名
[root@localhost rpm]# rpm --addsign --define "_gpg_name devtools " nginx-1.28.0-release.el7.x86_64.rpm [root@localhost rpm]# rpm -qlp nginx-1.28.0-release.el7.x86_64.rpm
/nginx.service
/nginx/conf/nginx.conf
...
/opt/app/nginx/nginx/sbin/nginx#安装测试
[root@localhost ~]# yum install nginx-1.28.0-release.el7.x86_64.rpm
Installed:nginx.x86_64 0:1.28.0-release.el7 Complete![root@localhost nginx]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)Active: active (running) since Thu 2025-05-01 14:11:02 CST; 2min 10s agoProcess: 17859 ExecStart=/opt/app/nginx/sbin/nginx (code=exited, status=0/SUCCESS)Process: 17856 ExecStartPre=/opt/app/nginx/sbin/nginx -t (code=exited, status=0/SUCCESS)Process: 17854 ExecStartPre=/usr/bin/rm -f /opt/app/nginx/logs/nginx.pid (code=exited, status=0/SUCCESS)Main PID: 17861 (nginx)CGroup: /system.slice/nginx.service├─17861 nginx: master process /opt/app/nginx/sbin/nginx└─17862 nginx: worker process[root@localhost nginx]# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 17861/nginx: master 完成!
关于rpmbuild 简单使用
-
打包之前的准备工作
主要是借鉴了【RPMBUILD从入门到放弃】 https://blog.csdn.net/weixin_50902636/article/details/140215376
# 精确控制 RPM 包的构建过程 rpmbuild 会适合你
[root@t33 webhook]# yum install rpm-build rpmdevtools
[root@t33 webhook]# rpmbuild --version
RPM version 4.11.3[root@t33 rpmbuild]# su - rpmbuild #网上建议用普通用户,如果不清楚编译的命令的话,可能出问题。[rpmbuild@t33 rpmbuild]$ rpmbuild --showrc|grep macros #配置文件读取优先级
Macro path: ····:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros # ~/.rpmmacros 默认的配置文件 #目录结构
[rpmbuild@t33 rpmbuild]# rpmbuild --showrc | grep topdir
-14: _builddir %{_topdir}/BUILD #源码解压的目录。
-14: _buildrootdir %{_topdir}/BUILDROOT #临时目录,构建过程中测试安装的目录,最终将其中的打包成 RPM 包。用完即删
-14: _rpmdir %{_topdir}/RPMS #最终输出的RPM 存放目录。
-14: _sourcedir %{_topdir}/SOURCES #源文件、依赖、补丁等 需要的都放这 存放目录。
-14: _specdir %{_topdir}/SPECS #配置文件.spec 存放目录。
-14: _srcrpmdir %{_topdir}/SRPMS #源码包 .src.rpm 存放目录。
-14: _topdir %{getenv:HOME}/rpmbuild #默认的工作目录[root@t33 rpm]# rpm --eval “%{_topdir}”
“/root/rpmbuild”/root/rpmbuild/ #因为机器之前编译安装过sniproxy
├── BUILD
│ └── sniproxy-0.6.1
│ ├── configure···
├── BUILDROOT
├── RPMS
│ └── x86_64 #RPM包根据硬件平台不同分类
│ ├── sniproxy-0.6.1-1.el7.x86_64.rpm
│ └── sniproxy-debuginfo-0.6.1-1.el7.x86_64.rpm
├── SPECS
└── SRPMS└── sniproxy-0.6.1-1.el7.src.rpm#.rpmmacros 自定义不了 使用 export RPM_CONFIG_FILE=*** 会找不到目录的
#自定义宏 其他的宏 可以查看 https://blog.csdn.net/weixin_50902636/article/details/140215376
[rpmbuild@t33 rpmbuild]$ cat /home/rpmbuild/.rpmmacros
%_topdir /usr/local/src/rpm/rpmbuild #下面的目录可以不用指定, 默认都是%{_topdir} 目录下了
%_builddir %{_topdir}/BUILD #也可以写绝对路径,这里也是想试试宏
%_buildrootdir %{_topdir}/BUILDROOT
%_rpmdir %{_topdir}/RPMS
%_sourcedir %{_topdir}/SOURCES
%_specdir %{_topdir}/SPECS
%_srcrpmdir %{_topdir}/SRPMS
#还可以加其他宏
%_builduser rpmbuild[root@t33 rpm]# rpm --eval “%{_builduser}” #默认路径下的可以查看,rpm没有找到指定rpmmacros
“rpmbuild”#创建目录
[rpmbuild@t33 rpmbuild]$ mkdir -p {BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
-
rpmbuild 打包 - sniproxy 为例
#以sniproxy 为例 https://github.com/dlundquist/sniproxy/
#sniproxy 安装步骤如下
yum install autoconf automake curl gettext-devel libev-devel pcre-devel perl pkgconfig rpm-build udns-devel
./autogen.sh && ./configure && make dist #命令后会生成 sniproxy-0.6.1.tar.gz 生成发布包,可以理解为源码包
rpmbuild --define "_sourcedir `pwd`" -ba redhat/sniproxy.spec #"_sourcedir `pwd` 将本地目录变成源文件目录,进行编译打包
yum install /root/rpmbuild/RPMS/x86_64/sniproxy-0.6.0-1.el6.x86_64.rpm
-----------------------------------------------------------------------------------------
#工作正式开始 #需要解析sniproxy.spec,将所需要的文件放置到自定义目录下
[rpmbuild@t33 sniproxy-0.6.1]# mv sniproxy-0.6.1.tar.gz /usr/local/src/rpm/rpmbuild/SOURCES/ #拷贝 make dist 生成的源码包
[rpmbuild@t33 sniproxy-0.6.1]# cp -rfp redhat/sniproxy.spec /usr/local/src/rpm/rpmbuild/SPECS/[rpmbuild@t33 SPECS]$ cat sniproxy.spec #定义配置文件
#和fpm一样的字段定义
Name: sniproxy
·····
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) #用到了宏,还是用了name 、version 定义的变量
BuildRequires: autoconf, automake, curl, libev-devel, pcre-devel, perl, gettext-devel, udns-devel #依赖%description
Proxies incoming HTTP ···%prep
%setup -q #解压并cd到目录中%build
%configure CFLAGS="-I/usr/include/libev" #configure编译
make %{?_smp_mflags} #开启并行编译%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT #安装#脚本有
#%pre 安装前需要做的任务,如:创建用户
#%post 安装后需要做的任务 如:自动启动的任务
#%preun 卸载前需要做的任务 如:停止任务
#%postun 卸载后需要做的任务 如:删除用户,删除/备份业务数据%pre #在客户端安装前执行
if [ $1 -eq 1 ]; then #Spec文件中判断是升级or卸载 根据 $1,$2判断echo %{_builduser} #显示一下_builduser自定义宏%define Localtime 1990-01-01 #自定义变量echo %{Localtime}
fi%clean
rm -rf $RPM_BUILD_ROOT #BUILDROOT 用完即清理%files #设置文件属性
%defattr(-,root,root,-) #目录下的文件不指定 都继承此权限
%{_sbindir}/sniproxy%doc #文档
%{_mandir}/man8/sniproxy.8.gz
%{_mandir}/man5/sniproxy.conf.5.gz%changelog
* Thu Mar 16 2023 Dustin Lundquist <dustin@null-ptr.net 0.6.1-1
···#编译打包 步骤可以跳过,直接执行-ba
rpmbuild -bp 从开始执行到pre阶段 BUILD 有解压文件了
rpmbuild -bc 从开始执行执行到build阶段
rpmbuild -bi 从开始执行执行到install阶段 BUILDROOT开始有文件了,包含 -bl 阶段了
rpmbuild -bl 检查spec中的%file段 文件是否齐全rpmbuild -ba 从开始执行编译后生成*.rpm和* src.rpm-bb 只生成*.rpm-bs 只生成*.src.rpm
-
客户端安装验证
[root@localhost ~]# yum install sniproxy-0.6.1-1.el7.x86_64.rpm
Dependencies Resolved
=====================================================================================================================================================Package Arch Version Repository Size
=====================================================================================================================================================
Installing:sniproxy x86_64 0.6.1-1.el7 /sniproxy-0.6.1-1.el7.x86_64 86 k
Installing for dependencies:udns x86_64 0.4-3.el7 epel 60 kTransaction Summary
=====================================================================================================================================================
Install 1 Package (+1 Dependent package)
Running transactionInstalling : udns-0.4-3.el7.x86_64 1/2
rpmbuild # pre脚本输出
1990-01-01 # pre脚本输出 Installing : sniproxy-0.6.1-1.el7.x86_64 2/2 Verifying : udns-0.4-3.el7.x86_64 1/2 Verifying : sniproxy-0.6.1-1.el7.x86_64 2/2 Installed:sniproxy.x86_64 0:0.6.1-1.el7 Dependency Installed:udns.x86_64 0:0.4-3.el7 Complete!
参阅:
fpm安装和使用fpm打包rpm
fpm - packaging made simple — fpm - packaging made simple 1.9.0 documentation
RPMBUILD从入门到放弃
相关文章:
小白上手RPM包制作
目录 rpm常用命令 安装环境-Ruby 安装环境-fpm 关于服务器 打包-打包二进制工程 .fpm配置文件 打包-打没有文件的包 RPM 包微调 命令行参数 fpm --help RPM 签名 打包-制作NGINX的RPM包 关于rpmbuild 简单使用 打包之前的准备工作 rpmbuild 打包 - sniproxy …...
电商热销榜的5种实现方案
文章目录 1. MySQL 聚合查询:传统统计法2. Redis Sorted Set:内存排行榜3. Elasticsearch 实时聚合:搜索专家4. 缓存异步更新:榜单的幕后推手5. 大数据离线批处理:夜间魔法师 博主介绍:全网粉丝10w、CSDN合…...
车载诊断进阶篇 --- 车载诊断概念
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
AD 多层线路及装配图PDF的输出
装配图的输出: 1.点开‘智能PDF’ 2. 设置显示顶层: 设置显示底层: 多层线路的输出 同样使用‘智能PDF’...
FramePack - 开源 AI 视频生成工具
🎬 项目简介 由开发者 lllyasviel 创建的一个轻量级动画帧处理工具库,专门用于游戏开发、动画制作和视频处理中的帧序列打包与管理。该项目采用高效的算法实现,能够显著提升动画资源的处理效率。 此 AI 视频生成项目,旨在通过低显…...
“this”这个关键字
一、什么是“this”? 简单来说,“this”是每个非静态成员函数隐含的指针,它指向调用该成员函数的那个对象本身。 换句话说,当你调用对象的方法时,编译器会自动传入一个指针,指向你调用的“那个对象”&…...
问题处理——在ROS2(humble)+Gazebo+rqt下,无法显示仿真无人机的相机图像
文章目录 前言一、问题展示二、解决方法:1.下载对应版本的PX42.下载对应版本的Gazebo3.启动 总结 前言 在ROS2的环境下,进行无人机仿真的过程中,有时需要调取无人机的相机图像信息,但是使用rqt,却发现相机图像无法显示…...
广度和深度优先搜索(BFS和DFS)
1. 广度和深度优先搜索(BFS和DFS) 1.1. Python实现BFS和DFS from collections import dequeclass Graph:"""无向图类,支持添加边,并实现了 BFS(广度优先搜索)和 DFS(深度优先搜…...
React和Vue在前端开发中, 通常选择哪一个
React和Vue的选择需结合具体需求: 选React的场景 大型企业级应用,需处理复杂状态(如电商、社交平台)团队熟悉JavaScript,已有React技术栈积累需要高度灵活的架构(React仅专注视图层,可自由搭配…...
Vue3学习(组合式API——reactive()和ref()函数详解)
目录 一、reactive()函数。 (1)介绍与使用。 (2)简单案例演示。 二、ref()函数。 (1)介绍与使用。 (2)简单案例演示。 <1>ref()函数获取响应式对象的本质与底层。 <2>基…...
数据结构 -- 树形查找(一)二叉排序树
二叉排序树 二叉排序树的定义 二叉排序树,又称二叉查找树 一棵二叉树或者是空二叉树,或者是具有以下性质的二叉树: 左子树上所有结点的关键字均小于根结点的关键字 右子树上所有结点的关键字均大于根结点的关键字 左子树和右子树又各是…...
【实战教程】从零实现DeepSeek AI多专家协作系统 - Spring Boot+React打造AI专家团队协作平台
🚀 本项目是DeepSeek大模型应用系列的V3版本,基于V1和V2版本的功能进行全面升级,引入了多智能体协作机制! 系列教程推荐阅读顺序: 【V1版本】零基础搭建DeepSeek大模型聊天系统 - Spring BootReact完整开发指南【V2版本…...
React事件机制
React事件机制 React 的事件机制是其实现高效、跨浏览器交互的核心系统,它通过 合成事件(SyntheticEvent)、事件委托(Event Delegation)、事件冒泡(Bubbling) 和 事件派发(Dispatch…...
LeetCode 45. 跳跃游戏 II(中等)
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…...
LeetCode 热题 100 437. 路径总和 III
LeetCode 热题 100 | 437. 路径总和 III 大家好,今天我们来解决一道经典的二叉树问题——路径总和 III。这道题在 LeetCode 上被标记为中等难度,要求计算二叉树中节点值之和等于给定目标值 targetSum 的路径数目。 问题描述 给定一个二叉树的根节点 ro…...
力扣.1471数组的k个最强值,力扣.1471数组的k个最强值力扣1576.替换所有的问号力扣1419.数青蛙编辑力扣300.最长递增子序列
目录 力扣.1471数组的k个最强值 力扣1576.替换所有的问号 力扣1419.数青蛙编辑 力扣300.最长递增子序列 力扣.1471数组的k个最强值 class Solution {public static int[] getStrongest(int[] arr,int k) {if(karr.length){return arr;}int []retnew int[k];int narr.lengt…...
使用itextsharp5.0版本来合并多个pdf文件并保留书签目录结构
using System; using System.Collections.Generic; using System.IO; using iTextSharp.text; using iTextSharp.text.pdf;public class PdfMergeUtility {/// <summary>/// 合并多个PDF文件并保留书签目录结构/// </summary>/// <param name"inputFiles&q…...
2025-5-15Vue3快速上手
1、setup和选项式API之间的关系 (1)vue2中的data,methods可以与vue3的setup共存 (2)vue2中的data可以用this读取setup中的数据,但是反过来不行,因为setup中的this是undefined (3)不建议vue2和vue3的语法混用…...
Kafka消费者分组机制深度解析
一、集群协调者 1.1 GroupCoordinator的元数据管理 每个Broker内置的GroupCoordinator实例通过哈希算法确定消费者组的归属权。其内存模型维护三个核心数据结构: 成员注册表:采用跳表结构存储消费者ID与心跳时间戳,支持快速查询和过期检测…...
Python 类变量与实例变量完全指南:区别、使用场景及常见陷阱
类变量与实例变量的区别总结 代码示例 class Example:class_var "我是类变量,所有实例共享我" # 类变量def __init__(self, name):self.name name # 实例变量,每个实例独有def modify_class_var(self, new_value):Example.class_var ne…...
Ubuntu Linux bash的相关默认配置文件内容 .profile .bashrc, /etc/profile, /etc/bash.bashrc等
文章目录 文件的source顺序/etc/profile:系统级配置/etc/bash.bashrc:bash终端的系统级配置~/.profile:用户级配置~/.bashrc bash:终端的主要配置~/.bash_logout:bash终端登出时清理 建议的额外配置: 安装 …...
redis解决常见的秒杀问题
title: redis解决常见的秒杀问题 date: 2025-03-07 14:24:13 tags: redis categories: redis的应用 秒杀问题 每个店铺都可以发布优惠券,保存到 tb_voucher 表中;当用户抢购时,生成订单并保存到 tb_voucher_order 表中。 订单表如果使用数据…...
Springboot3自定义starter笔记
场景:抽取聊天机器人场景,它可以打招呼。 效果:任何项目导入此 starter 都具有打招呼功能,并且问候语中的人名需要可以在配置文件中修改。 创建自定义 starter 项目,引入 spring-boot-starter 基础依赖。 <dependen…...
Modern C++(一)基本概念
1、基本概念 1.1、注释 注释在翻译阶段3会被替换为单个空白字符从程序中移除 1.2、名字与标识符 标识符是一个由数字、下划线、大小写字符组成的任意长度序列。有效的标识符首个字符必须是以A-Z、a-z、下划线开头,。有效的标识符其他字符可以是0-9、A-Z、a-z、下…...
Apache HttpClient 5 用法-Java调用http服务
Apache HttpClient 5 核心用法详解 Apache HttpClient 5 是 Apache 基金会推出的新一代 HTTP 客户端库,相比 4.x 版本在性能、模块化和易用性上有显著提升。以下是其核心用法及最佳实践: 一、添加依赖 Maven 项目: <dependency><…...
Python中plotext 库详细使用(命令行界面中直接绘制各种图形)
更多内容请见: python3案例和总结-专栏介绍和目录 文章目录 plotext概述1.1 plotext介绍1.2 安装二、基本用法2.1 简单绘图2.2 散点图2.3 折线图2.4 条形图2.5 直方图2.6 标题和坐标轴标签2.7 网格和坐标轴2.8 颜色和样式2.9 多图叠加三、高级功能3.1 多图绘制3.2 对数坐标3.3…...
【Java Web】速通JSON
参考笔记:JavaWeb 速通JSON_java webapi调用传json与head-CSDN博客 目录 1.JSON基本介绍 2.JSON串的格式 3.JSON在客户端/浏览器的使用 3.1 JavaScript对象和JSON串的相互转换 3.2 案例演示 4.JSON在服务端的使用 4.1 基本说明 4.2 应用场景 4.2.1 JSON字…...
Ubuntu 20.04 LTS 中部署 网页 + Node.js 应用 + Nginx 跨域配置 的详细步骤
Ubuntu 20.04 LTS 中部署 网页 Node.js 应用 Nginx 跨域配置 的详细步骤 一、准备工作1、连接服务器2、更新系统 二、安装 Node.js 环境1、安装 Node.js 官方 PPA(用于获取最新稳定版):2、安装 Node.js 和 npm(LTS 长期支持版本…...
java中XML的使用
文章目录 什么是XML特点XML作用XML的编写语法基本语法特殊字符编写 约束XML的书写格式DTD文档schema文档属性命名空间XML命名空间的作用 解析XML的方法DOM解析XMLDOM介绍DOM解析包:org.w3c.dom常用接口DOM解析包的使用保存XML文件添加DOM节点修改/删除DOM节点 S…...
Spark SQL 之 Analyzer
Spark SQL 之 Analyzer // Special case for Project as it supports lateral column alias.case p: Project =>val resolvedNoOuter = p.projectList.map(resolveExpressionByPlanChildren(_, p...
Java - Junit框架
单元测试:针对最小的功能单元(方法),编写测试代码对该功能进行正确性测试。 Junit:Java语言实现的单元测试框架,很多开发工具已经集成了Junit框架,如IDEA。 优点 编写的测试代码很灵活,可以指某个测试方法…...
麒麟系统ARM64架构部署mysql、jdk和java项目
麒麟系统ARM64架构部署mysql、jdk和java项目 一、mysql8的安装 操作步骤: 先下载mysql安装包 下载地址:https://downloads.mysql.com/archives/community/ 由于官网里,mysql5.7以及更低版本不支持arm版本的,只能安装mysql8。…...
修复“ImportError: DLL load failed while importing lib: 找不到指定的程序”笔记
#工作记录 一、问题描述 在运行CosyVoice_For_Windows项目时,出现以下报错: Traceback (most recent call last): File "D:\ProgramData\anaconda3\envs\CosyVoice\Lib\pydoc.py", line 457, in safeimport module __import__(path) …...
vllm量化03—INT4 W4A16
本系列基于Qwen2.5-7B,学习如何使用vllm量化,并使用benchmark_serving.py、lm_eval 测试模型性能和评估模型准确度。 测试环境为: OS: centos 7 GPU: nvidia l40 driver: 550.54.15 CUDA: 12.3本文是该系列第3篇——INT4 W4A16 一、量化 f…...
VScode各文件转化为PDF的方法
文章目录 代码.py文件.ipynb文本和代码夹杂的文件方法 1:使用 VS Code 插件(推荐)步骤 1:安装必要插件步骤 2:安装 `nbconvert`步骤 3:间接导出(HTML → PDF)本文遇见了系列错误:解决方案:问题原因步骤 1:降级 Jinja2 至兼容版本步骤 2:确保 nbconvert 版本兼容替代…...
AI日报 · 2025年5月15日|GPT-4.1 登陆 ChatGPT
AI日报 2025年5月15日|GPT-4.1 登陆 ChatGPT 1、OpenAI 在 ChatGPT 全面开放 GPT-4.1 与 GPT-4.1 mini 北京时间 5 月 14 日晚,OpenAI 在官方 Release Notes 中宣布:专为复杂代码与精细指令场景打造的 GPT-4.1 正式加入 ChatGPT࿰…...
高效管理多后端服务:Nginx 配置与实践指南
在现代的 Web 开发和运维中,一个系统往往由多个后端服务组成,每个服务负责不同的功能模块。例如,一个电商网站可能包括用户服务、订单服务和支付服务,每个服务都运行在独立的服务器或容器中。为了高效地管理这些服务并提供统一的访…...
从代码学习深度学习 - 实战 Kaggle 比赛:图像分类 (CIFAR-10 PyTorch版)
文章目录 前言1. 读取并整理数据集1.1 读取标签文件1.2 划分训练集和验证集1.3 整理测试集1.4 执行数据整理2. 图像增广2.1 训练集图像变换2.2 测试集(和验证集)图像变换3. 读取数据集3.1 创建 Dataset 对象3.2 创建 DataLoader 对象4. 定义模型4.1 获取 ResNet-18 模型4.2 损…...
什么是路由器环回接口?
路由器环回接口(LoopbackInterface)是网络设备中的一种逻辑虚拟接口,不依赖物理硬件,但在网络配置和管理中具有重要作用。以下是其核心要点: 一、基本特性 1.虚拟性与稳定性 环回接口是纯软件实现的逻辑接口&#x…...
【高频面试题】LRU缓存
文章目录 1 相关前置知识(OS)2 面试题 16.25. LRU 缓存2.1 题面2.2 示例2.3 解法1 (双端队列哈希表)思路 2.4 解法2思路 3 参考 1 相关前置知识(OS) 为什么需要页面置换算法:当进程运行时&…...
Golang
本文来源 :腾讯元宝 Go语言(又称Golang)是由Google开发的一种现代编程语言,自2009年发布以来,因其简洁性、高性能和内置并发支持而广受欢迎。以下是关于Go语言的核心特点和优势的总结: 1. 核心特点…...
20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤
20250515配置联想笔记本电脑IdeaPad总是使用独立显卡的步骤 2025/5/15 19:55 百度:intel 集成显卡 NVIDIA 配置成为 总是用独立显卡 百度为您找到以下结果 ?要将Intel集成显卡和NVIDIA独立显卡配置为总是使用独立显卡,可以通过以下步骤实现?ÿ…...
『已解决』Python virtualenv_ error_ unrecognized arguments_--wheel-bundle
📣读完这篇文章里你能收获到 🐍 了解 virtualenv 参数错误的原因及解决方案📦 学习如何正确配置 Python 虚拟环境 文章目录 前言一、问题描述1.1 错误现象1.2 影响范围 二、问题分析2.1 根本原因 三、解决方案3.1 兼容处理3.2 完整解决方案 …...
使用 Apache POI 生成 Word 文档
创建一个包含标题、段落和表格的简单文档。 步骤 1:添加依赖 确保你的项目中已经添加了 Apache POI 的依赖。如果你使用的是 Maven,可以在 pom.xml 中添加以下内容: <dependency><groupId>org.apache.poi</groupId>...
表记录的检索
1.select语句的语法格式 select 字段列表 from 表名 where 条件表达式 group by 分组字段 [having 条件表达式] order by 排序字段 [asc|desc];说明: from 子句用于指定检索的数据源 where子句用于指定记录的过滤条件 group by 子句用于对检索的数据进行分组 ha…...
【PX4飞控】在 Matlab Simulink 中使用 Mavlink 协议与 PX4 飞行器进行交互
这里列举一些从官网收集的比较有趣或者实用的功能。 编写 m 脚本与飞行器建立 UDP 连接,并实时可视化 Mavlink 消息内容,或者读取脚本离线分析数据。不光能显示 GPS 位置或者姿态等信息的时间曲线,可以利用 Matlab Plot 功能快速定制化显示一…...
文章复现|(1)整合scRNA-seq 和空间转录组学揭示了子宫内膜癌中 MDK-NCL 依赖性免疫抑制环境
https://www.frontiersin.org/journals/immunology/articles/10.3389/fimmu.2023.1145300/full 目标:肿瘤微环境(TME)在子宫内膜癌(EC)的进展中起着重要作用。我们旨在评估EC的TME中的细胞群体。 方法:我们从GEO下载了EC的单细胞RNA测序(scRNA-seq)和空…...
自用Vscode 配置c++ debug环境
前言 使用vscode配置c debug环境的好处 1、可以借助vscode方便轻量的扩展和功能 2、避免了传统使用gdb 复杂按键以及不够直观的可视化 3、方便一次运行,断点处查看变量,降低找bug难度 4、某大公司项目采用类似配置,经过实践检验 配置c运行环…...
STM32单片机内存分配详细讲解
单片机的内存无非就两种,内部FLASH和SRAM,最多再加上一个外部的FLASH拓展。在这里我以STM32F103C8T6为例子讲解FLASH和SRAM。 STM32F103C8T6具有64KB的闪存和20KB的SRAM。 一. Flash 1.1 定义 非易失性存储器,即使在断电后,其所…...
从算力困境到创新突破:GPUGEEK如何重塑我的AI开发之旅
目录 从算力困境到创新突破:GPUGEEK如何重塑我的AI开发之旅开发者的算力挣扎:一个不得不面对的现实AI算力市场的尴尬现状:为什么我们需要另辟蹊径1. 资源分配失衡与价格壁垒2. 技术门槛与环境复杂性 GPUGEEK深度剖析:不只是又一个…...