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

通向架构师的道路之Apache整合Tomcat

一、先从J2EE工程的通用架构说起

这是一个通用的Web即B/S工程的架构,它由:

ü   Web Server

ü   App Server

ü   DB Server

三大部分组成,其中:

²  Web Server

置于企业防火墙外,这个防火墙,大家可以认为是一个CISCO路由器,然后在CISCO路由器上开放了两个端口为:80和443。

80端口:用于正常的http访问

443端口:用于https访问,即如果你在ie里打入https://xxx.xxx.xx这样的地址,默认

走的是443这个端口。

WebServer专门:用于解析HTML、JS(JavaScript)、CSS、JPG/GIF等图片格式文件、TXT、

VBSCRIPT、PHP等一切一切“静态”网页内容。

²  App Server

置于企业防火墙内,它和Web Server之间的连接必须且一定为内部IP连接。

外部IP:即Internet IP地址,我们的web服务器一般会有一个内部IP一个外部IP,因此在这里,我们的App Server没有任何外部IP,只有内部IP,所以我在这边说App Server与Web Server只能以内部IP形式连接。

打比方说我们用的是tomcat,它的端口为8080,那么这个ip地址上的8080端口只能由任何内部ip才能访问,外部的internet是访问不了的,这样做就是为了安全。

App Server用于解析我们的任何需要Java编译器才能解析的“动态”网页,其实App Server本身也能解析任何静态网页的。

那么我们这样来想一下:

我们让负责专门解析静态网页的Web Server来解析html等内容,而让App Server专门用于解析任何需要Java编译器才能解析的东西,让它们“两人”各司其职。这样作的好处:

1)    为App Server“减压”,同时也提高了performance

2)    不用再把8080这个端口暴露在internet上了,也很安全,必经我们的app server上可是有我们的代码的,就算是编译过的代码也容易被“反编译”,这是很不安全的。

3)    为将来的进一步的“集群扩展”打好了基础

²  DB Server

打 比方说我们用的是Oracle,它需要通过1521与App Server进行连接是不是?那么这个1521我们称为数据库连接端口,如果把它暴露在Internet上,是不是在危险了点?就算我们的密码很复杂,但 对于高明的黑客来说,要攻破你的口令也只是时间上的问题而己。

因此我们把我们的DB Server也和App Server一样,置于内网的防火墙。任何的DB连接与管理只能通过内网即在公司企业内部来访问,就是这个道理。

二、动手来架构

2.1 Oracle数据加的安装与配置

DB(Oracle)我已经为大家准备好了,连接信息为:

IP

10.225.10x.xx

Port:

1521

Username/Password:

xxx/xxx

Sid:

Jcoedb1

url:

jdbc:oracle:thin:@10.225.10x.xx:1521:xxx

所以,根据上述的架构,我们可以把如下这样的一份清单丢给NSS或者是相关的网络管理部门,让他们给我们开通相应的端口:

Web Server

对外IP: xxx.xxx.xxx.xxx
对内IP:10.225.xxx.xxx

向internet开通80与443端口

App Server

对内IP: 10.225.xxx.xxx

只对10.225.段的ip开放8080,8009等端口,

Db Server

对内IP: 10.225.xxx.xxx

只对10.225.段的ip开放1521端口

2.2 App Server的安装

直接解压tomcat至你的本地如:d:\tomcat,我这边用的目录名叫tomcat2,大家随意,最好名字能够越简单越好d:\tomcat或者c:\tomcat就行,不要放得太“深”。

2.3 Web Server的安装

我们在这边将安装Apache For Win 2.2.x,它将占用你机器的80和443端口。因此如果你机器上有任何程序占用你的80和443端口,必须将它关闭掉,比如说:

我们装有微软的IIS,这本身也是一个WebServer,那么请你将它关闭:

ControlPanel->Administrative Tools->Service,找到IISAdmin和,将它全部关闭并将启动方式设为:manual以便于不用每次重启后再要去手动关闭一下。

然后用netstat –ano找到任何还在占用80端口的程序,将它关闭掉。

2.4 开始安装Apache Http Server

我们将安装这个版本的apache http server作为我们今后一直使用的Web Server

 这边的server name你们要填入自己的server的真实名,不能用我这个,这个servername如:shnlap93.cts.com只能够我用,这个名称是全局唯一的,和你的IP一样。

https://img-my.csdn.net/uploads/201206/28/1340851533_9763.jpg

https://img-my.csdn.net/uploads/201206/28/1340851561_4353.jpg

 选全部安装

https://img-my.csdn.net/uploads/201206/28/1340851595_3238.jpg

装 完后你会多出一个这样的图标来,点击该图标,里面有用于控制apache http server的启动、停止与重启等操作选项。同时在你们的“服务”面板中,也能发现这样的一个服务项,它启动时默认是随着系统的启动而启动的,我们把它改 成“手动”吧,因为将来我们还要安装IBM Http Server来作练习。

https://img-my.csdn.net/uploads/201206/28/1340851739_1628.jpg

装完后,在Apache2.2启动的前提下,打开一个ie输入http://localhost,你将会得到这样的一个页面,就说明你的Apache的安装是成功的。

https://img-my.csdn.net/uploads/201206/28/1340851769_6496.jpg

2.5 Apache的配置

学Java的人,必须会这个Apache的配置,要不然你怎么模拟环境、搭建环境和架构环境?光会Coding是远远不够的,你将永远只配作个码农。。。嘿嘿嘿!有很多人发觉到了后面JAVA学不上去了,关键因素在于:配置。

你会配环境了,那么你就能模拟任何客户方、开发方的环境。

你会配环境了,你的代码将来上线时才能成功运行。

你会配环境了,所以整个工程的技术核心就是你。

跟着我的教程,你们将会安装和运行达近百个各种软件与配置,搞得你一股臭味一股臭味!!

你准备好了没有?

当然,不用怕,因为我的配置都是实际运行的环境,所以网上的一些东西你可以不用去看,因为很多人都是在网上进行拷贝、复制,有时也不经过验证,会让你走很多的弯路到头来还是落得个BUG一天世界,就看我的教程吧。

Apache的配置主要集中在httpd.conf文件,它位于你的安装目录,比如:

D:\tools\httpd\conf\

我们用ultraedit或者相关文本编辑工具打开它,来看它的内容:

先来查找到如下这一行:

#ServerName

我们可以得到如下这一行内容:

#ServerName shnlap93.cts.com:80

这就是我们的主机名了,我们可以将前面的“#”去掉,并将其改为:

ServerName 10.225.106.35:80

改完后存盘,在重启你的Apache2.2前我们先测试一下我们的Apache的配置文件是否改得对:

https://img-my.csdn.net/uploads/201206/28/1340851804_5602.jpg

 如果在你点了Test Configuration后,黑屏一闪而过,说明你的改动无误,否则这个黑屏会一直停留在当前状态,并且告诉你,你的配置改动有错,错在哪里。

重新启动你的Apache

https://img-my.csdn.net/uploads/201206/28/1340851833_5227.jpg

找到如下这行:

DocumentRoot

你会发下有这样的一行内容:

DocumentRoot "D:/tools/httpd/htdocs"

这个叫作DocumentRoot即webroot,即:发布目录,发布在这个目录下的任何工程都会在Apache服务开启时被装载成标准的web工程,我们现在动手来把这个WebRoot定位到我们自己的发布目录中去吧。

DocumentRoot "d:/www"

我们把它改到了d盘的www目录中去了,然后我们在该目录中放入一个index.html文件,内容为:

Hey man, apache works!

重启我们的Apache服务,来测试一下:

https://img-my.csdn.net/uploads/201206/28/1340851859_5395.jpg

 嘿嘿,我们得到了什么?禁止访问,为什么?

找到下面这一段:

    Options FollowSymLinks

    AllowOverride None

    Order deny,allow

    deny from all

看到了没?

现在,把这个”deny from all”改成”allow fromall’吧。

    Options FollowSymLinks

    AllowOverride None

    Order deny,allow

    allow from all

修改完后重启你的Apache服务

https://img-my.csdn.net/uploads/201206/28/1340851884_3119.jpg

 Ok,我们的Apache的发布目录已经成功更改到了d:\www目录下了,我们再来做一个实验:

我们在IE浏览器中输入: http://localhost/css/,我们看到了什么?

https://img-my.csdn.net/uploads/201206/28/1340851911_5401.jpg

这还了得,用户如果是个初级黑客都可以知道我们的服务器上有哪些文件,哪些目录甚至可以直接看到我们的文件内容,怎么办?

找到下面这行

Options FollowSymLinks indexes

把它注掉改成下面这样

#Options FollowSymLinks indexes

Options None

不要急,再往下找,还有

Options Indexes FollowSymLinks

又来一个,再改掉

#Options Indexes FollowSymLinks

Options None

改完这两条后重启你的Apache服务

再次打开一个新的IE,输入:http://localhost/css/,我们看到了如下的界面:

https://img-my.csdn.net/uploads/201206/28/1340851936_1802.jpg

 好了,Apache的基本配置完成了即:

1)  基本的安全配置,不允许目录访问

2)  把WebRoot改到另一个物理目录上而不使用Apache自带的WebRoot目录

2.6 整合Apache与Tomcat

Apache(Web Server)负责处理HTML静态内容;

Tomcat(App Server)负责处理动态内容;

https://img-my.csdn.net/uploads/201206/28/1340851960_9390.jpg

其实就是上述这样的一个架构,下面是原理

1)      Apache装有一个模块,这个模块叫mod_jk

2)      Apache通过80端口负责解析任何静态web内容

3)      任何不能解析的内容,用表达式告诉mod_jk,让mod_jk派发给相关的app server去解释。

通过上述的文字描述我们可以得知:

1)  我们需要在Apache中先装一个mod_jk

2)  我们需要在httpd.conf中写点表达式

下面来实现。

1)      把 mod_jk-1.2.31-httpd-2.2.3.so手工copy进我们的Apache安装目录的modules目录下,这个文件的全名叫: mod_jk-1.2.31-httpd-2.2.3.so,大家可以从ftp上的“/JavaArchitect/mod_jk/”目录中获取,因为这 个文件是我用C++在本地重新编译过的,网上下载的是src即源码,省去大家再去编译的时间了,而且一些其它网上下载的mod_jk.so是无法使用的。

2)      用ultraedit打开httpd.conf文件,跑到文件最后面加入以下几行:

LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so

JKWorkersFile conf/workers.properties

JkLogFile logs/mod_jk.log

ServerAdmin localhost

DocumentRoot d:/www/

ServerName localhost

DirectoryIndex index.html index.htm index.jsp index.action

ErrorLog logs/shsc-error_log.txt

CustomLog logs/shsc-access_log.txt common

JkMount /*WEB-INF ajp13

JkMount /*j_spring_security_check ajp13

JkMount /*.action ajp13

JkMount /servlet/* ajp13

JkMount /*.jsp ajp13

JkMount /*.do ajp13

JkMount /*.action ajp13

JkMount /*fckeditor/editor/filemanager/connectors/*.* ajp13

JkMount /fckeditor/editor/filemanager/connectors/* ajp13

关键的是这两句:

LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so

JKWorkersFile conf/workers.properties

代表:

ü   Apache载入一个额外的插件,用于连接tomcat。

ü   连接时的配置参数描述位于Apache安装目录的/conf目录下的一个叫workers.properties文件中,mod_jk一般使用ajp13协议连接,使用的是tomcat的8009端口。

3)      Worker.properties文件内容如下:

workers.tomcat_home=d:/tomcat2

workers.java_home=C:/jdk1.6.32

ps=/

worker.list=ajp13

worker.ajp13.port=8009

worker.ajp13.host=localhost

worker.ajp13.type=ajp13

4)      告诉我们的Apache,哪些是要交给tomcat来解析,除此之外都由Apache本身来解析

ServerAdmin localhost

DocumentRoot d:/www/

ServerName localhost

DirectoryIndex index.html index.htm index.jsp index.action

ErrorLog logs/shsc-error_log.txt

CustomLog logs/shsc-access_log.txt common

JkMount /*WEB-INF ajp13

JkMount /*j_spring_security_check ajp13

JkMount /*.action ajp13

JkMount /servlet/* ajp13

JkMount /*.jsp ajp13

JkMount /*.do ajp13

JkMount /*.action ajp13

JkMount /*fckeditor/editor/filemanager/connectors/*.* ajp13

JkMount /fckeditor/editor/filemanager/connectors/* ajp13

大家看到没,所有的/servlet/*都由tomcat负责解析,所有的jsp, .do, .action都由tomcat解析。

此处还有一个特殊的/fckeditor,这个是我们使用的一个博客编辑器,这个因为是servlet的,因此也需要交给tomcat铁析。

5)      将/cbbs工程布署到tomcat的webapps目录下

6)      将/cbbs同样手工copy一份到d:/www目录下

7)      删除d:/www/cbbs/WEB-INF这个目录,嘿嘿,因为d:/www下的东西是由Apache解析的,所有的WEB-INF下的都是Java,我们只需要布署在tomcat下即可,是不是?

8)      重启tomcat,重启Apache,在ie中直接输入: http://localhost/cbbs,使用sally/abcdefg登录,操作一下,一切成功

Oh…yeah, tomcat+apache一步搞定。

三、用于实验的cbbs工程配置

最后附上cbbs布署需要用到的配置,相关的工程可通过ftp的” /Java Architect/Project/”下的cbbs.zip来获取。

ü   在tomcat中打开server.xml加入:

driverClassName="oracle.jdbc.OracleDriver"

factory="org.apache.commons.dbcp.BasicDataSourceFactory"

maxActive="25" maxIdle="100" maxWait="5000" name="jdbc/eltds"

password="xxx"

type="javax.sql.DataSource"

url="jdbc:oracle:thin:@10.225.101.51:1521:jcoedb1"

         username="xxx"/>

ü   手工在d盘根目录建立一个upload目录,在此目录内再建立一个image目录。
ü   在tomcat中打开context.xml加入

相关文章:

通向架构师的道路之Apache整合Tomcat

一、先从J2EE工程的通用架构说起 这是一个通用的Web即B/S工程的架构,它由: Web Server App Server DB Server 三大部分组成,其中: Web Server 置于企业防火墙外,这个防火墙,大家可以认为是…...

如何消除“信息孤岛”对业务增长的威胁?

根据CMSWire的数据,员工平均每天要花36%的时间来查找和整合信息。但44%的情况下,他们找不到信息。这种时间和精力的浪费就是信息孤岛造成的。 什么是信息孤岛? 当部门存储数据并限制其他人访问数据时,就会出现信息孤岛&#xff…...

Kali部署dvwa和pikachu靶场

kali换源 进入 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/kali kali-rolling main non-free contrib deb-src https://mirrors.aliyun.com/kali kali-rolling main non-free contrib替换完后更新源 apt-get upadteDVWA靶场环境搭建 使用git从github上把DV…...

​LeetCode解法汇总722. 删除注释

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给一个 C 程序,删除程序中的注释。这个程序source是一个数组&#x…...

Linux中的firewall-cmd

2023年8月4日,周五上午 目录 打开端口关闭端口查看某个端口是否打开查看当前防火墙设置firewall-cmd中的服务在防火墙中什么是服务?为什么会有服务?打开或关闭服务查看某个服务是否打开firewall-cmd中的 zones查看所有可用的zones&#xff0…...

python 最大归一化

最大归一化是将数据转化到[-1,1]范围之间。公式如下 其中|X|max为x特征的绝对值的最大值。 数据标准化算法介绍—数据建模工具_预处理_Max_字段 """ 最大绝对值归一化(max abs normalization ):也就是将数值变为单位长度&…...

Netty:ByteBuf写入数据、读出数据

介绍 Netty的ByteBuf数据位置索引是0开始的。 可以用ByteBuf的getByte(int index)方法从指定位置读出一字节,这个操作不会改变ByteBuf的readerIndex 或者 writerIndex 的位置。如果index小于0,或者index 1大于ByteBuf的容量,就会抛出IndexO…...

C++(15):面向对象程序设计

面向对象程序设计概述 面向对象程序设计(object-oriented programming)的核心思想是数据抽象、继承和动态绑定。 1.使用数据抽象,可以将类的接口与实现分离; 2.使用继承,可以定义相似的类型并对其相似关系建模&#x…...

2023牛客暑期多校训练营6-A Tree

2023牛客暑期多校训练营6-A Tree https://ac.nowcoder.com/acm/contest/57360/A 文章目录 2023牛客暑期多校训练营6-A Tree题意解题思路代码 题意 解题思路 最大价值和这个数据范围,一眼 d p dp dp。 直接在树上并不好处理,问题是如何有效转化、处理…...

Vc - Qt - QPainter::SmoothPixmapTransform及QPainter::Antialiasing

QPainter::SmoothPixmapTransform是一个标志,用于指定绘制操作中的平滑像素变换行为。当使用QPainter绘制一幅图像时,设置SmoothPixmapTransform标志可以使图像变换过程更加平滑,减少锯齿状边缘的出现。此标志通常用于绘制缩放后图像的情况。…...

【练习】条件变量:创建三个线程 id号为ABC,三个线程循环打印自己的ID号,运行顺序为 ABCABC

题目&#xff1a; 创建三个线程 id号为ABC&#xff0c;三个线程循环打印自己的ID号&#xff0c;运行顺序为 ABCABC......要求使用条件变量 #include <stdio.h> #include <pthread.h> #include <unistd.h>//创建互斥锁 pthread_mutex_t mutex PTHREAD_MUTE…...

SpringBoot项目修改中静态资源,只需刷新页面无需重启项目(附赠—热加载)

初衷 &#x1f4a2;初衷&#x1f4a2; 因为一遍遍修改并重启项目觉得很麻烦&#xff0c;所以刚开始就自己给项目配置了热加载&#xff0c;但奈何代码更新还是慢&#xff0c;还不如我重启一遍项目的速度&#xff0c;所以放弃了自己上网找到的热加载配置。直到我debugger前端代码…...

clear_data_code_2d_model

dev update off () dev close window () ImageFiles:-./二维条码/read_image(Image&#xff0c;ImageFiles 十二维条码原图.png)dev_open_window_fit_image(Image&#xff0c;0&#xff0c;0&#xff0c;-&#xff0c;-1&#xff0c;WindowHandle)set_display_font (WindowHan…...

“深入剖析JVM:揭秘Java虚拟机的工作原理“

标题&#xff1a;深入剖析JVM&#xff1a;揭秘Java虚拟机的工作原理 摘要&#xff1a;本文将深入探讨Java虚拟机&#xff08;JVM&#xff09;的工作原理&#xff0c;包括JVM的架构、内存管理、垃圾回收、即时编译等关键技术。通过对JVM的剖析&#xff0c;我们可以更好地理解Ja…...

elementui表格table中实现内容的换行

问题 elementui 中的 table 行内的内容不能进行换行。 解决方法 思路&#xff1a; 利用 作用域插槽 结合 v-html&#xff0c;通过作用域插槽传递内容到表格行内&#xff0c;再通过 v-html 进行内容的替换。 代码&#xff1a; <el-table:data"tableData"stri…...

java 框架

目录 Spring 如何解决 bean 的循环依赖?什么是 AOP?Spring 如何实现的?BeanFactory 和 ApplicationContext 有什么区别?介绍一下 Spring bean 的生命周期Spring 的隔离级别Spring 框架用到了哪些设计模式?并举出典型例子Spring 如何解决 bean 的循环依赖? Spring中引入三…...

死锁的发生原因和怎么避免

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 例如&#xff1a;项目场景&#xff1a;示例:通过蓝牙芯片(HC-05)与手机 APP 通信&#xff0c;每隔 5s 传输一批传感器数据(不是很大) 问题描述 死锁&#xff0c;简单来说就是两个或者两个以上的线程在…...

visual studio 生成dll文件以及修改输出dll文件名称操作

目录 visual studio 生成dll文件以及修改dll文件名称一、准备测试代码二、设置导出dll属性三、生成dll文件 .lib .dll .pdb 的简单介绍dll文件使用方式lib文件使用方式1、动态链接 &#xff08;原理&#xff09;2、静态链接&#xff1a; visual studio 生成dll文件以及修改dll文…...

【Leetcode】73.矩阵置零

一、题目 1、题目描述 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例1: 输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例2: 输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1…...

zabbix监控mysql容器主从同步状态并告警钉钉/企业微信

前言&#xff1a;被监控的主机已经安装和配置mysql主从同步&#xff0c;和zabbix-agent插件。 mysql创建主从同步&#xff1a;http://t.csdn.cn/P4MYq centos安装zabbix-agent2&#xff1a;http://t.csdn.cn/fx74i mysql主从同步&#xff0c;主要监控这2个参数指标&#xf…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...