TOMCAT多实例及调优

news2025/1/21 2:55:20

一、JVM相关理论

(一)JVM组成

1.JVM组成部分

类加载子系统: 使用Java语言编写.java Source Code文件,通过javac编译成.class Byte Code文件。class loader类加载器将所需所有类加载到内存,必要时将类实例化成实例

运行时数据区: 最消耗内存的空间,需要优化

执行引擎: 包括JIT (JustInTimeCompiler)即时编译器, GC垃圾回收器

本地方法接口: 将本地方法栈通过JNI(Java Native Interface)调用Native Method Libraries, 比如:C,C++库等,扩展Java功能,融合不同的编程语言为Java所用

2.JVM运行时数据区
JVM运行时数据区域由下面部分构成

2.1 方法区 Method Area 或 元空间 Metaspace(线程共享)

方法区是所有线程共享的内存空间

在JDK 1.8之前,这个区域被称为“永久代”(Permanent Generation),其中存储了类的元数据,如类信息、字段描述符、方法描述符、常量池等。但实例变量存放在堆内存中。
自从JDK 1.8开始,“永久代”被彻底移除,取而代之的是元空间,它不在Java堆中而是使用本地内存(Native Memory),存储类的元数据和其他运行时常量池的信息。
元空间大小可以通过参数 -XX:MaxMetaspaceSize 进行限制。

2.2 Java堆 heap (线程共享):堆在虚拟机启动时创建,存放创建的所有对象信息。如果对象无法申请到可用内存将抛出OOM异常.堆是靠GC垃圾回收器管理的,通过-Xmx -Xms 指定最大堆和最小堆空间大小

JVM管理的最大内存区域,所有线程共享。
所有对象实例和数组都在堆上分配内存。
堆被进一步划分为新生代(Young Generation)和老年代(Old Generation),新生代又可细分为Eden区、From Survivor区和To Survivor区,这是根据垃圾收集策略来区分的。
垃圾回收机制主要关注堆中的对象是否还被引用,未被引用的对象将在GC过程中被回收。

2.3 虚拟机栈 Java stack (线程私有):

每个线程同样有自己的虚拟机栈,也是线程私有的。
虚拟机栈中包含多个栈帧,每个栈帧对应一个方法调用,存储局部变量表、操作数栈、动态链接信息和方法出口等数据。
当线程执行一个方法时,就会创建一个新的栈帧并压入栈顶;当方法返回或抛出异常时,对应的栈帧会被弹出。

2.4 程序计数器 Program Counter Register (线程私有)

是一块较小的内存空间,每个线程都有一个独立的程序计数器。

它用于存储当前线程执行字节码指令的位置,是线程私有的。

在多线程环境中,程序计数器的存在可以确保线程切换后能恢复到正确的执行位置。

2.5 本地方法栈 Native Method stack (线程私有)

类似于虚拟机栈,但服务于JNI(Java Native Interface)调用的本地(非Java)方法。
本地方法栈也会有线程私有的栈帧,不过它们是用来支持本地方法调用的。

(二)垃圾回收

在堆内存中如果创建的对象不再使用,仍占用着内存,此时即为垃圾.需要及时进行垃圾回收,从而释放内存空间给其它对象使用

1.确定垃圾
Java虚拟机(JVM)在处理垃圾回收时采用了多种算法和策略

引用计数法

这是最基础的垃圾回收算法之一,通过为每个对象添加一个引用计数器,每当有一个地方引用它时,计数器加一;当引用失效时,计数器减一。当计数器为0时,说明该对象不再被任何对象引用,可以作为垃圾回收。
现代JVM并不采用引用计数法,因为它无法有效处理循环引用问题。

可达性分析算法(Reachability Analysis)

当前主流JVM如HotSpot使用的是可达性分析算法,也称为追踪式垃圾收集(Tracing Garbage Collection)。该算法以一系列被称为GC Roots的对象作为起点,通过从这些根节点开始向下搜索所有可达对象来确定哪些是活动对象。不可达的对象被认为是可回收的垃圾。

2.垃圾收集算法
基于可达性分析的结果,JVM有几种不同的垃圾收集算法来执行具体的垃圾清除:

标记-清除(Mark-Sweep):首先标记出所有需要回收的对象,然后进行清除操作。缺点是会产生内存碎片。

复制(Copying):将内存分为两块,每次只用其中一块,在垃圾回收时,将存活对象复制到另一块未使用的内存区域,然后清除原区域的所有内容。如新生代中的 Eden 区和两个 Survivor 区就是采用这种方式,常见于Minor GC中。

标记-整理(Mark-Compact):与标记-清除类似,但在清除不可达对象后,会将剩余的存活对象“压缩”在一起,从而解决内存碎片问题。老年代通常采用此方式或其变种。

分代收集(Generational Collection):根据对象生命周期的不同,将堆内存划分为新生代和老年代,分别采用不同的垃圾回收算法,比如新生代常使用复制算法,老年代使用标记-整理或标记-清除+压缩等。

在不同场景选择最合适的算法

二、java内存调整相关参数
(一)JVM 内存常用相关参数
Java 命令行参考文档: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

帮助:man java

选项分类

-选项名称 此为标准选项,所有HotSpot都支持

-X选项名称 为稳定的非标准选项

-XX:选项名称 非标准的不稳定选项,下一个版本可能会取消

参数说明举例
-Xms设置应用程序初始使用的堆内存大小(年轻代+老年代)-Xms2g
-Xmx设置应用程序能获得的最大堆内存早期JVM不建议超过32G,内存管理效率下降-Xms4g
-XX:NewSize设置初始新生代大小-XX:NewSize=128m
-XX:MaxNewSize设置最大新生代内存空间-XX:MaxNewSize=256m
-Xmnsize同时设置-XX:NewSize 和 -XX:MaxNewSize,代-Xmn1g
-XX:NewRatio以比例方式设置新生代和老年代-XX:NewRatio=2new/old=1/2
-XX:SurvivorRatio以比例方式设置eden和survivor(S0或S1)-XX:SurvivorRatio=6eden/survivor=6/1new/survivor=8/1
-Xss设置每个线程私有的栈空间大小,依据具体线程-Xss256k

标准选项

输入java查看选项

[root@centos60 manager]#java
用法: java [-options] class [args...]
           (执行类)
   或  java [-options] -jar jarfile [args...]
           (执行 jar 文件)
其中选项包括:
    -d32      使用 32 位数据模型 (如果可用)
    -d64      使用 64 位数据模型 (如果可用)
    -server      选择 "server" VM
                  默认 VM 是 server,
                  因为您是在服务器类计算机上运行。


    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
                  用 : 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<值>
                  设置系统属性
    -verbose:[class|gc|jni]
                  启用详细输出
    -version      输出产品版本并退出
    -version:<值>
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  需要指定的版本才能运行
    -showversion  输出产品版本并继续
    -jre-restrict-search | -no-jre-restrict-search
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  在版本搜索中包括/排除用户专用 JRE
    -? -help      输出此帮助消息
    -X            输出非标准选项的帮助
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度启用断言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<libname>[=<选项>]
                  加载本机代理库 <libname>, 例如 -agentlib:hprof
                  另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jarpath>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<imagepath>
                  使用指定的图像显示启动屏幕
有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html

非标准的稳定选项

输入java -XX查看

[root@centos60 manager]#java  -X
    -Xmixed           混合模式执行(默认)
    -Xint             仅解释模式执行
    -Xbootclasspath:<用 : 分隔的目录和 zip/jar 文件>
                      设置引导类和资源的搜索路径
    -Xbootclasspath/a:<用 : 分隔的目录和 zip/jar 文件>
                      附加在引导类路径末尾
    -Xbootclasspath/p:<用 : 分隔的目录和 zip/jar 文件>
                      置于引导类路径之前
    -Xdiag            显示附加诊断消息
    -Xnoclassgc        禁用类垃圾收集
    -Xincgc           启用增量垃圾收集
    -Xloggc:<file>    将 GC 状态记录在文件中(带时间戳)
    -Xbatch           禁用后台编译
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xss<size>        设置 Java 线程堆栈大小
    -Xprof            输出 cpu 分析数据
    -Xfuture          启用最严格的检查,预计会成为将来的默认值
    -Xrs              减少 Java/VM 对操作系统信号的使用(请参阅文档)
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xshare:off       不尝试使用共享类数据
    -Xshare:auto      在可能的情况下使用共享类数据(默认)
    -Xshare:on        要求使用共享类数据,否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:system
                      (仅限 Linux)显示系统或容器
                      配置并继续
    -XshowSettings:all
                      显示所有设置并继续
    -XshowSettings:vm 显示所有与 vm 相关的设置并继续
    -XshowSettings:properties
                      显示所有属性设置并继续
    -XshowSettings:locale
                      显示所有与区域设置相关的设置并继续

-X 选项是非标准选项。如有更改,恕不另行通知
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/hy199707/article/details/136483760

有不稳定选项的当前生效值:java -XX:+PrintFlagsFinal

查看所有不稳定选项的默认值:java -XX:+PrintFlagsInitial

(二)Tomcat的JVM参数设置

默认不指定,-Xmx大约使用了1/4的内存,当前本机内存指定约为1G。

在bin/catalina.sh中增加一行

 -Xms 和 -Xmx 建议两个值调一样大小

 

-server: 指定使用服务器模式运行Java虚拟机,这种模式通常针对服务端应用进行了优化,提供更好的性能。

-Xms1024m: 设置Java堆的初始大小为1024MB。这意味着在JVM启动时就将分配1GB的内存作为堆空间的最小值。

-Xmx1024m: 设置Java堆的最大大小也为1024MB。这意味着堆内存的上限是1GB,在程序运行过程中,如果需要更多内存且不超过这个限制,JVM会动态增加堆内存;但如果超过这个值,且无法释放足够的空间,则可能会抛出 OutOfMemoryError 错误。

-XX:NewSize=300m: 设置新生代(Young Generation)的初始大小为300MB。新生代是Java堆中的一部分,主要存储新创建的对象和生命周期较短的对象。

-XX:MaxNewSize=400m: 设置新生代的最大大小为400MB。这意味着新生代的内存占用可以在300MB至400MB之间自动调整。

 可以通过状态页来查看修改之后的状态

#这段信息描述的是Java虚拟机(JVM)的内存使用情况,具体来说是针对垃圾回收器
#为Parallel Scavenge(PS)的HotSpot JVM。
#每个部分分别表示不同的内存区域: 
 
PS Eden Space
 
'这是年轻代(Young Generation)的一部分,主要用于存储新创建的对象'
 
PS Old Gen
 
'这是老年代(Old Generation),存放长期存活或晋升过来的对象' 
 
PS Survivor Space
'同样是年轻代的一部分,用于保存在年轻代中经历过一次GC但尚未被回收的对象'
 
Code Cache
'非堆内存区域,用于存储JIT编译后的机器码' 
 
Compressed Class Space
'另一个非堆内存区域,当类空间过大时,经过压缩的类会被存放到此区域以节省内存'
 
Metaspace
'从Java 8开始取代了永久代(PermGen),用于存储类元数据信息。这里显示的最大容量为-0.00 MB,
这意味着Metaspace的大小可以动态调整,不受固定上限限制'

这些设置共同决定了JVM在处理Java应用程序时如何管理和分配内存资源,以满足程序的运行需求,并尽可能地提高系统的稳定性和性能。不过,请注意,这些设置应当根据实际的应用场景、硬件资源和负载情况来合理配置。

Tomcat默认安装下的缺省配置并不适合生产环境,它可能会频繁出现假死现象需要重启,只有通过不断压测优化才能让它最高效率稳定的运行。优化主要包括三方面,分别为操作系统优化(内核参数优化),Tomcat配置文件参数优化,Java虚拟机(JVM)调优。

#Tomcat 配置文件参数优化##
常用的优化相关参数如下:
【redirectPort】如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS   443 请求时,则转发至此属性定义的 8443 端口。

【maxThreads】Tomcat使用线程来处理接收的每个请求,这个值表示Tomcat可创建的最大的线程数,即支持的最大并发连接数,默认值是 200。

【minSpareThreads】最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 10。

【maxSpareThreads】最大备用线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值是-1(无限制)。一般不需要指定。

【processorCache】进程缓冲器,可以提升并发请求。默认值是200,如果不做限制的话可以设置为-1,一般采用maxThreads的值或者-1。

【URIEncoding】指定 Tomcat 容器的 URL 编码格式,网站一般采用UTF-8作为默认编码。

【connnectionTimeout】网络连接超时,单位:毫秒,设置为 0 表示永不超时,这样设置有隐患的。通常默认 20000 毫秒就可以。

【enableLookups】是否反查域名,以返回远程主机的主机名,取值为:true 或 false,如果设置为 false,则直接返回 IP 地址,为了提高处理能力,应设置为 false。

【disableUploadTimeout】上传时是否使用超时机制。应设置为 true。

【connectionUploadTimeout】上传超时时间,毕竟文件上传可能需要消耗更多的时间,这个根据你自己的业务需要自己调,以使Servlet有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效。

【acceptCount】指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为 100 个。

【maxKeepAliveRequests】指定一个长连接的最大请求数。默认长连接是打开的,设置为1时,代表关闭长连接;为-1时,代表请求数无限制

【compression】是否对响应的数据进行GZIP压缩,off:表示禁止压缩;on:表示允许压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为 off,压缩数据后可以有效的减少页面的大小,一般可以减小 1/3 左右,节省带宽。

【compressionMinSize】表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是 2048。

【compressableMimeType】压缩类型,指定对哪些类型的文件进行数据压缩。

【noCompressionUserAgents="gozilla, traviata"】对于以下的浏览器,不启用压缩
#如果已经进行了动静分离处理,静态页面和图片等数据就不需做 Tomcat 处理,也就不要在 Tomcat 中配置压缩了。

以上是一些常用的配置参数,还有好多其它的参数设置,还可以继续深入的优化,HTTP Connector 与 AJP Connector 的参数属性值,可以参考官方文档的详细说明进行学习。


vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/11.1" 
connectionTimeout="20000" 
redirectPort="8443" 
--71行--插入
minSpareThreads="50" 
enableLookups="false" 
disableUploadTimeout="true" 
acceptCount="300" 
maxThreads="500" 
processorCache="500"
URIEncoding="UTF-8" 
maxKeepAliveRequests="100"
compression="on" 
compressionMinSize="2048" 
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>

 

三、TOMCAT多实例

安装好JDK与TOMCAT服务后进行配置

(一)建立两个服务文件

 (二)建立system管理文件

(三)修改监听端口号

 <Server port="8006" shutdown="SHUTDOWN">        
#22行,修改Server prot,默认为8005 -> 修改为8006
 
<Connector port="9527" protocol="HTTP/1.1"       
#69行,修改Connector port,HTTP/1.1  默认为8080 -> 修改为8081
 
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />    
#116行,修改Connector port AJP/1.3,默认为8009 -> 修改为8010

修改完毕后,启动第二个tomcat服务:systemctl  start  tomcat1

使用客户端去访问tomcat服务器监听的不同端口,可以看到,都提供了应用服务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1495875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1908_Arm Cortex-M3的实现

1908_Arm Cortex-M3的实现 全部学习汇总&#xff1a; g_arm_cores: ARM内核的学习笔记 (gitee.com) 这是第一次看一份这样的手册&#xff0c;之前的MCU编程基本上就是专注于软件接口方面。而OS等方面的一些功能基本上都是用了现成的解决方案&#xff0c;因此也就没有过多的关注…

NXP iMX8MM Cortex-M4 核心 GPT Capture 测试

By Toradex秦海 1). 简介 NXP i.MX8 系列处理器均为异构多核架构 SoC&#xff0c;除了可以运行 Linux 等复杂操作系统的 Cortax-A 核心&#xff0c;还包含了可以运行实时操作系统比如 FreeRTOS 的 Cortex-M 核心&#xff0c;本文就演示通过 NXP i.MX8MM 处理器集成的 Cortex-…

基于Springboot+Layui餐厅点餐系统

一、项目背景 在互联网经济飞速发展的时代&#xff0c;网络化企业管理也在其带领下快速兴起&#xff0c;开发一款自主点餐系统会受到众多商家的青睐。现如今市场上的人力资源价格是非常高昂的&#xff0c;一款自主点餐系统可以减少餐厅的人力开销&#xff0c;将服务员从繁忙的…

建立自己的富足金字塔

本文的理论参考&#xff1a; 1、《金字塔原理》&#xff0c;可以简述为&#xff1a;上下层互为支撑的结构化表达&#xff0c;通常为1-3-9结构&#xff1b;完全穷举、互不交叉&#xff0c;或不重不漏MECE的分门分类&#xff1b;真实有效&#xff0c;真知灼见。 2、《金线》在金字…

贷齐乐错误的waf引起的SQL注入漏洞复现

君衍. 一、环境介绍1、第一道WAF2、第二道WAF 二、环境部署1、模拟源码2、连接数据库源码3、数据库创建4、测试 三、源码分析1、模拟WAF2、注入思路3、PHP下划线特性4、完成假设 四、联合查询注入1、测试回显字段2、爆出库名3、爆出表名4、爆出表下的列名4、爆出flag 一、环境介…

AI大模型与小模型之间的“脱胎”与“反哺”(第五篇)

一、背景 AI大模型与小模型之间存在一种“脱胎”与“反哺”的关系&#xff0c;这种关系在AI技术的发展中起到了重要的作用。 首先&#xff0c;我们来理解一下“脱胎”的概念。在AI领域&#xff0c;大模型通常具有更大的参数量、更强的表达能力和更高的计算需求。这些大模型通…

第一个 Angular 项目 - 添加路由

第一个 Angular 项目 - 添加路由 前置项目是 第一个 Angular 项目 - 添加服务&#xff0c;之前的切换页面使用的是 ngIf 对渲染的组件进行判断&#xff0c;从而完成渲染。这一步的打算是添加路由&#xff0c;同时添加 edit recipe 的功能(同样通过路由实现) 用到的内容为&…

RabbitMQ 交换器

RabbitMQ 交换器 官方例子 http://www.rabbitmq.com/getstarted.html direct 如上图所示&#xff0c;两个队列绑定到了direct交换器上&#xff0c;第一个队列绑定的 binding key 为 orange &#xff0c;第二个队列有两个绑定&#xff0c;分别是 black 和 green 。 如上图所示…

vue+element模仿实现云码自动验证码识别平台官网

一、项目介绍 项目使用传统vue项目结构实现&#xff0c;前端采用element实现。 element官网&#xff1a;Element - The worlds most popular Vue UI framework 云码官网地址&#xff1a;云码-自动验证码识别平台_验证码识别API接口_免费验证码软件 项目截图&#xff0c;支持…

一键安装conda-batch脚本

conda的安装可以更简化些&#xff0c;即使用batch文件&#xff0c;具体步骤如下&#xff1a; 新建文本文档&#xff0c;并改后缀名为.bat 使用文本编辑器编辑&#xff0c;并输入内容如下 echo offSET MINICONDA_INSTALLER_PATHminiconda3_installer.exe SET MINICONDA_UR…

实现一个网页版的简易猜数字游戏

实现一个网页版的简易猜数字游戏 效果 代码截图 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…

基于Matlab实现免疫荧光图像中的区域定位算法

基于Matlab实现免疫荧光图像中的区域定位算法 免疫荧光法。以荧光染料为标记物,试纸条为载体,发生抗原抗体特异性反应,根据免疫复合物被激发的荧光强度对待测物进行定量分析[。该方法具有环境要求不高、操作简单快速、无污染且荧光染料丰富等优点。 常用于食品安全检测过程中…

Python实现选择排序算法

Python实现选择排序算法 以下是使用Python实现选择排序算法的示例代码&#xff1a; def selection_sort(arr):n len(arr)for i in range(n):min_index i# 找到未排序部分的最小元素的索引for j in range(i 1, n):if arr[j] < arr[min_index]:min_index j# 将最小元素与…

【BUG】cmd运行wmic提示‘wmic‘ 不是内部或外部命令

cmd运行wmic提示‘wmic‘ 不是内部或外部命令 解决办法 将C:\Windows\System32\wbem添加到系统环境变量

《系统架构设计师教程(第2版)》第6章-据库设计基础知识-01-数据库基本概念

文章目录 1. 概述1.1 基本概念1&#xff09;信息 (Information)2&#xff09;数据 (Data)3&#xff09;数据库 (DB)4&#xff09;数据库系统(DBS)5&#xff09;数据库管理系统&#xff08;DBMS&#xff09; 1.2 数据库技术的发展1.2.1 人工管理阶段1.2.2 文件系统阶段1&#xf…

SQL中如何添加数据

SQL中如何添加数据 一、SQL中如何添加数据&#xff08;方法汇总&#xff09;二、SQL中如何添加数据&#xff08;方法详细解说&#xff09;1. 使用SQL脚本&#xff08;推荐&#xff09;1.1 在表中插入1.1.1 **第一种形式**1.1.2 **第二种形式**SQL INSERT INTO 语法示例SQL INSE…

代码学习记录10

随想录日记part10 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.03 主要内容&#xff1a;今天的主要内容是深入了解数据结构中栈和队列&#xff0c;并通过三个 l e e t c o d e leetcode leetcode 题目深化认识。 20. 有效的括号1047. 删除字符串中的所有…

day13_微服务监控Nginx(微服务集成SBA)

文章目录 1 微服务系统监控1.1 监控系统的意义1.2 SBA监控方案1.3 SBA实战1.3.1 创建SBA服务端1.3.2 微服务集成SBA 1.4 微服务集成logback1.5 配置邮件告警 2 Nginx2.1 Nginx简介2.2 下载和安装2.2.1 方式1&#xff1a;window本地安装2.2.1.1 下载2.2.1.2 安装2.2.1.3 目录结构…

如何使用 CSS object-fit 进行图片的缩放和裁剪

简介 在处理图片时&#xff0c;你可能会遇到需要保持原始宽高比的情况。保持宽高比可以防止图片被拉伸或压缩而出现失真。解决这个问题的常见方法是使用 background-image CSS 属性。更现代的方法是使用 object-fit CSS 属性。 在本文中&#xff0c;你将探索 object-fit CSS …

【系统安全加固】Centos 设置禁用密码并打开密钥登录

文章目录 一&#xff0c;概述二&#xff0c;操作步骤1. 服务器端生成密钥2. 在服务器上安装公钥3.下载私钥到本地&#xff08;重要&#xff0c;否则后面无法登录&#xff09;4. 修改配置文件&#xff0c;禁用密码并打开密钥登录5. 重启sshd服务6. 配置xshell使用密钥登录 一&am…