程序员@老李 - 技术 https://blog.mostion.com/category/tech/ 技术人生 - technical-life Rocky Linux 8 中禁用 IPv6 并仅启用 IPv4 https://blog.mostion.com/archives/56/ 2025-06-17T13:42:00+08:00 在 Rocky Linux 8 中禁用 IPv6 并仅启用 IPv4,可以通过以下步骤完成(推荐使用 nmcli 或直接修改内核参数):方法 1:通过 nmcli 禁用 IPv6(临时生效,重启后保留)1. 查看当前网络连接名称nmcli connection show输出示例(假设连接名为 ens192):NAME UUID TYPE DEVICE ens192 518fd4a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx ethernet ens1922. 禁用 IPv6 并仅启用 IPv4nmcli connection modify ens192 ipv6.method "disabled" nmcli connection up ens192 # 重新激活连接方法 2:修改网络配置文件(永久生效)1. 编辑网卡配置文件vi /etc/sysconfig/network-scripts/ifcfg-ens192在文件中添加或修改以下参数:IPV6INIT=no IPV6_AUTOCONF=no IPV6_DEFROUTE=no IPV6_FAILURE_FATAL=no2. 重启网络服务systemctl restart NetworkManager方法 3:通过内核参数禁用 IPv6(全局禁用)1. 修改 GRUB 配置vi /etc/default/grub在 GRUB_CMDLINE_LINUX 行添加 ipv6.disable=1:GRUB_CMDLINE_LINUX="... ipv6.disable=1"2. 重新生成 GRUB 配置grub2-mkconfig -o /boot/grub2/grub.cfg3. 重启系统reboot验证 IPv6 是否已禁用# 检查网卡是否无 IPv6 地址 ip a | grep inet6 # 应无输出 # 验证内核参数 cat /proc/cmdline | grep ipv6.disable # 应显示 `ipv6.disable=1`(如果使用方法3)恢复 IPv6(如需启用)1. 恢复 nmcli 配置nmcli connection modify ens192 ipv6.method "auto" nmcli connection up ens1922. 删除内核参数编辑 /etc/default/grub 移除 ipv6.disable=1,重新生成 GRUB 并重启。注意事项优先级:方法 1/2 仅针对特定网卡,方法 3 是全局禁用。生产环境中建议优先使用方法 1 或 2,避免影响其他服务。兼容性:某些应用程序(如 Docker、Kubernetes)可能依赖 IPv6,禁用前需测试。防火墙:如果使用 firewalld,IPv6 规则会自动失效,无需额外操作。通过上述步骤,系统将仅使用 IPv4 通信。 MySQL 8 禁用表名大小写敏感 https://blog.mostion.com/archives/55/ 2025-06-17T13:41:52+08:00 在 Rocky Linux 8 上使用 yum(或 dnf)安装 MySQL 8 后,如果需要 禁用表名大小写敏感(即强制表名存储为小写),需修改配置文件并重新初始化数据目录。以下是具体步骤:步骤 1:修改 MySQL 配置文件1. 编辑 MySQL 配置文件(默认路径):vi /etc/my.cnf或(如果存在):vi /etc/my.cnf.d/mysql-server.cnf2. 在 [mysqld] 段落下添加以下参数:[mysqld] lower_case_table_names=1参数说明:lower_case_table_names=1:表名存储为小写,比较时不区分大小写。注意:MySQL 8 仅在初始化时允许修改此参数,后续更改需重新初始化数据目录!步骤 2:停止 MySQL 服务systemctl stop mysqld步骤 3:删除原有数据目录(谨慎操作!)rm -rf /var/lib/mysql/*此操作会删除所有数据库数据,确保已备份重要数据!步骤 4:重新初始化 MySQL 数据目录mysqld --initialize --user=mysql --lower-case-table-names=1关键点:--initialize:初始化数据目录。--user=mysql:指定运行用户。--lower-case-table-names=1:确保初始化时应用配置。步骤 5:启动 MySQL 服务systemctl start mysqld步骤 6:验证配置1. 登录 MySQL:mysql -u root -p(输入初始化时生成的临时密码,可通过 grep 'temporary password' /var/log/mysqld.log 查看)2. 检查参数是否生效:SHOW VARIABLES LIKE 'lower_case_table_names';输出应为:+------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | lower_case_table_names | 1 | +------------------------+-------+常见问题解决1. 初始化报错 --lower-case-table-names=1 无效原因:MySQL 8 要求此参数必须在首次初始化时设置,且不能后续修改。解决:确保数据目录 /var/lib/mysql/ 为空,重新执行初始化命令。2. 表名仍区分大小写原因:可能未正确删除旧数据目录或配置文件未生效。检查:cat /var/lib/mysql/auto.cnf | grep lower_case_table_names如果存在旧配置,需彻底清理数据目录。3. 权限问题若启动失败,检查日志:journalctl -u mysqld修复权限:chown -R mysql:mysql /var/lib/mysql chmod 750 /var/lib/mysql总结关键步骤:修改配置文件 → 删除数据目录 → 重新初始化。仅限新装:此方法适用于首次安装或可接受数据丢失的情况。生产环境:建议在测试环境验证后再操作,避免数据风险。⚠️ 注意:MySQL 8 默认不允许在初始化后修改 lower_case_table_names,因此必须通过重新初始化实现。 解决 Elasticsearch 不能以 root 用户运行的问题 https://blog.mostion.com/archives/54/ 2025-06-17T13:39:00+08:00 Elasticsearch 从 5.0 版本开始出于安全考虑,默认不允许以 root 用户运行。以下是解决这个问题的几种方法:方法一:创建专用用户运行 Elasticsearch(推荐)这是最安全和推荐的做法:创建 elasticsearch 用户和组:groupadd elasticsearch useradd -g elasticsearch elasticsearch更改 Elasticsearch 目录权限:chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/ chown -R elasticsearch:elasticsearch /var/lib/elasticsearch/ chown -R elasticsearch:elasticsearch /var/log/elasticsearch/以 elasticsearch 用户启动:sudo -u elasticsearch /usr/share/elasticsearch/bin/elasticsearch方法二:修改系统配置允许以 root 运行(不推荐)如果确实需要以 root 运行(仅用于测试环境):编辑 Elasticsearch 配置文件:vim /etc/elasticsearch/jvm.options添加以下 JVM 参数:-Des.insecure.allow.root=true或者修改启动脚本:vim /usr/share/elasticsearch/bin/elasticsearch在文件开头添加:ES_JAVA_OPTS="-Des.insecure.allow.root=true" export ES_JAVA_OPTS方法三:使用 systemd 服务(生产环境推荐)创建 systemd 服务文件:vim /etc/systemd/system/elasticsearch.service添加以下内容:[Unit] Description=Elasticsearch After=network.target [Service] User=elasticsearch Group=elasticsearch ExecStart=/usr/share/elasticsearch/bin/elasticsearch Restart=always LimitNOFILE=65536 [Install] WantedBy=multi-user.target启用并启动服务:systemctl daemon-reload systemctl enable elasticsearch systemctl start elasticsearch方法四:使用 Docker 运行如果你使用 Docker,可以这样运行:docker run -d --name elasticsearch \ -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ docker.elastic.co/elasticsearch/elasticsearch:7.9.2注意事项安全警告:在生产环境中以 root 运行 Elasticsearch 有严重安全风险文件权限:确保数据目录、日志目录和配置文件有正确的权限SELinux:如果启用了 SELinux,可能需要额外配置ulimit:可能需要增加文件描述符限制:ulimit -n 65536通过创建专用用户运行 Elasticsearch 是最佳实践,既能满足安全要求,又能保证服务正常运行。 SpringBoot 整合线程池 https://blog.mostion.com/archives/53/ 2024-08-29T10:01:00+08:00 步骤如下:1. 启动类加入 @EnableAsync 注解@SpringBootApplication @EnableAsync public class FacadeH5Application { public static void main(String[] args) { SpringApplication.run(FacadeH5Application.class, args); } }2. 在方法上加 @Async 注解@Async public void m1() { //do something }3. 创建线程池配置文件# 核心线程数 spring.task.execution.pool.core-size=8 # 最大线程数 spring.task.execution.pool.max-size=16 # 空闲线程存活时间 spring.task.execution.pool.keep-alive=60s # 是否允许核心线程超时 spring.task.execution.pool.allow-core-thread-timeout=true # 线程队列数量 spring.task.execution.pool.queue-capacity=100 # 线程关闭等待 spring.task.execution.shutdown.await-termination=false spring.task.execution.shutdown.await-termination-period= # 线程名称前缀 spring.task.execution.thread-name-prefix=task-@Configuration public class ThreadPoolConfig { @Bean public TaskExecutor taskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //设置核心线程数 executor.setCorePoolSize(10); //设置最大线程数 executor.setMaxPoolSize(20); //设置队列容量 executor.setQueueCapacity(20); //设置线程活跃时间 executor.setKeepAliveSeconds(30); //设置线程名称前缀 executor.setThreadNamePrefix("sendSms-"); //设置拒绝策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown(true); //设置线程池中任务的等待时间 executor.setAwaitTerminationSeconds(60); return executor; } }配置多个线程池@Configuration public class ThreadPoolConfig { @Bean("ThreadPool1") public TaskExecutor taskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); ...... return executor; } @Bean("ThreadPool2") public TaskExecutor taskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); ...... return executor; } }在使用 @Async 注解时就需要指定具体的线程池@Async("ThreadPool1") public void m1() { //do something } SpringBoot静态方法调用Spring容器bean的几种方案 https://blog.mostion.com/archives/49/ 2023-12-14T13:47:13+08:00 今天遇到一个问题,需要在静态方法中调用哦那个容器Bean,大致代码如下:@Autowired private static RedisUtil redisUtilBean; public static String getMsgByRedis(){ redisUtilBean.get("xxx") //这里redisUtilBean一定会是NULL值 }为什么会出现这种情况?原因是Spring容器的依赖注入是依赖set方法,而set方法是实例对象的方法,注入依赖时是无法注入静态成员变量的,在调用的时候依赖的Bean才会为null;解决方案一使用@PostConstruct注解:@Autowired private RedisUtil redisUtilBean; //由于静态方法无法使用注入的Bean 定义静态变量 private static RedisUtil redisUtil; //当容器实例化当前受管Bean时@PostConstruct注解的方法会被自动触发,借此来实现静态变量初始化 @PostConstruct public void init(){ this.redisUtil = redisUtilBean; } public static String getMsgByRedis(){ redisUtil.get("xxx") //这里可以正常使用 }解决方案二利用springboot的启动类中,SpringApplication.run() 方法返回的是一个ConfigurableApplicationContext对象通过定义static变量ConfigurableApplicationContext,利用容器的getBean方法获得依赖对象;@SpringBootApplication @EnableTransactionManagement public class Application { //定义静态的ApplicationContext public static ConfigurableApplicationContext applicationContext; public static void main(String[] args) { applicationContext = SpringApplication.run(Application.class, args); } } //调用 注意Application是我们SpringBoot的启动类 public static String getMsgByRedis(){ Application.applicationContext.getBean(RedisUtil .class).get("xxx") }解决方案三在我们以前SpringMVC中常用的工具类,通过实现ApplicationContextAware接口,网上也很多这里就把工具类贴出来即可;/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.toher.common.utils.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Map; /** * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext. * * @author 李怀明 * @version 2017-01-02 */ @Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; //实现ApplicationContextAware接口的context注入函数, 将其存入静态变量. public void setApplicationContext(ApplicationContext applicationContext) { SpringContextHolder.applicationContext = applicationContext; } //取得存储在静态变量中的ApplicationContext. public static ApplicationContext getApplicationContext() { checkApplicationContext(); return applicationContext; } //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. @SuppressWarnings("unchecked") public static <T> T getBean(String name) { checkApplicationContext(); return (T) applicationContext.getBean(name); } //从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. //如果有多个Bean符合Class, 取出第一个. @SuppressWarnings("unchecked") public static <T> T getBean(Class<T> clazz) { checkApplicationContext(); @SuppressWarnings("rawtypes") Map beanMaps = applicationContext.getBeansOfType(clazz); if (beanMaps != null && !beanMaps.isEmpty()) { return (T) beanMaps.values().iterator().next(); } else { return null; } } private static void checkApplicationContext() { if (applicationContext == null) { throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder"); } } public static HttpServletRequest getRequest() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } catch (Exception e) { return null; } } } 调用方法:RedisUtil redisUtil= (RedisUtil) SpringContextHolder.getBean(RedisUtil.class);结束,感谢! SpringBoot 自定义线程池 https://blog.mostion.com/archives/48/ 2023-11-29T08:51:00+08:00 我们都知道spring只是为我们简单的处理线程池,每次用到线程总会new 一个新的线程,效率不高,所以我们需要自定义一个线程池。本教程目录:自定义线程池配置spring默认的线程池1. 自定义线程池1.1 修改application.propertiestask.pool.corePoolSize=20 task.pool.maxPoolSize=40 task.pool.keepAliveSeconds=300 task.pool.queueCapacity=501.2 线程池配置属性类TaskThreadPoolConfig.javaimport org.springframework.boot.context.properties.ConfigurationProperties; /** * 线程池配置属性类 * Created by Fant.J. */ @ConfigurationProperties(prefix = "task.pool") public class TaskThreadPoolConfig { private int corePoolSize; private int maxPoolSize; private int keepAliveSeconds; private int queueCapacity; ...getter and setter methods... }1.3 创建线程池 TaskExecutePool.java/** * 创建线程池 * Created by Fant.J. */ @Configuration @EnableAsync public class TaskExecutePool { @Autowired private TaskThreadPoolConfig config; @Bean public Executor myTaskAsyncPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(config.getCorePoolSize()); //最大线程数 executor.setMaxPoolSize(config.getMaxPoolSize()); //队列容量 executor.setQueueCapacity(config.getQueueCapacity()); //活跃时间 executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); //线程名字前缀 executor.setThreadNamePrefix("MyExecutor-"); // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }1.4 创建线程任务/** * Created by Fant.J. */ @Component public class AsyncTask { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async("myTaskAsyncPool") //myTaskAsynPool即配置线程池的方法名,此处如果不写自定义线程池的方法名,会使用默认的线程池 public void doTask1(int i) throws InterruptedException{ logger.info("Task"+i+" started."); } }1.5 修改启动类给启动类添加注解@EnableAsync @EnableConfigurationProperties({TaskThreadPoolConfig.class} ) // 开启配置属性支持1.6 测试protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private AsyncTask asyncTask; @Test public void AsyncTaskTest() throws InterruptedException, ExecutionException { for (int i = 0; i < 100; i++) { asyncTask.doTask1(i); } logger.info("All tasks finished."); }2. 配置默认的线程池我本人喜欢用这种方式的线程池,因为上面的那个线程池使用时候总要加注解@Async("myTaskAsyncPool"),而这种重写spring默认线程池的方式使用的时候,只需要加@Async注解就可以,不用去声明线程池类。2.1 获取属性配置类这个和上面的TaskThreadPoolConfig类相同,这里不重复2.2 NativeAsyncTaskExecutePool.java 装配线程池/** * 原生(Spring)异步任务线程池装配类 * Created by Fant.J. */ @Slf4j @Configuration public class NativeAsyncTaskExecutePool implements AsyncConfigurer{ //注入配置类 @Autowired TaskThreadPoolConfig config; @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(config.getCorePoolSize()); //最大线程数 executor.setMaxPoolSize(config.getMaxPoolSize()); //队列容量 executor.setQueueCapacity(config.getQueueCapacity()); //活跃时间 executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); //线程名字前缀 executor.setThreadNamePrefix("MyExecutor-"); // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } /** * 异步任务中异常处理 * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable arg0, Method arg1, Object... arg2) { log.error("=========================="+arg0.getMessage()+"=======================", arg0); log.error("exception method:"+arg1.getName()); } }; } }2.3 线程任务类AsyncTask .java@Component public class AsyncTask { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async public void doTask2(int i) throws InterruptedException{ logger.info("Task2-Native"+i+" started."); } }2.4 测试@Test public void AsyncTaskNativeTest() throws InterruptedException, ExecutionException { for (int i = 0; i < 100; i++) { asyncTask.doTask2(i); } logger.info("All tasks finished."); } 2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-8] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native6 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-3] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native1 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native7 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native21 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native22 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native23 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native24 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native25 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native26 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native27 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native28 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native29 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native30 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native31 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native32 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native33 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native34 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native35 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native36 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native37 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native38 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native39 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native40 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native41 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native42 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native43 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native44 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native45 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native46 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native47 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-7] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native5 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-7] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native49 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-7] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native50 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-11] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native9 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native4 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native53 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native54 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native55 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native56 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native57 started.2018-03-25 21:23:07.659 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native58 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native59 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native60 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native61 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native62 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native63 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native64 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native65 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native66 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native67 started.2018-03-25 21:23:07.660 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native68 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-5] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native3 started.2018-03-25 21:23:07.655 INFO 4668 --- [ MyExecutor-4] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native2 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-8] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native19 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-2] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native0 started.2018-03-25 21:23:07.656 INFO 4668 --- [ MyExecutor-3] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native20 started.2018-03-25 21:23:07.657 INFO 4668 --- [ MyExecutor-10] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native8 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native48 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-7] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native51 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-11] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native52 started.2018-03-25 21:23:07.658 INFO 4668 --- [ MyExecutor-12] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native10 started.2018-03-25 21:23:07.661 INFO 4668 --- [ MyExecutor-13] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native11 started.2018-03-25 21:23:07.662 INFO 4668 --- [ MyExecutor-14] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native12 started.2018-03-25 21:23:07.662 INFO 4668 --- [ MyExecutor-15] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native13 started.2018-03-25 21:23:07.663 INFO 4668 --- [ MyExecutor-16] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native14 started.2018-03-25 21:23:07.663 INFO 4668 --- [ MyExecutor-17] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native15 started.2018-03-25 21:23:07.663 INFO 4668 --- [ MyExecutor-18] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native16 started.2018-03-25 21:23:07.663 INFO 4668 --- [ MyExecutor-19] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native17 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-20] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native18 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-21] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native69 started.2018-03-25 21:23:07.664 INFO 4668 --- [ main] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native89 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-6] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native90 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-22] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native70 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-5] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native91 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-5] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native92 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-8] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native93 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-2] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native94 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-10] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native95 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-3] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native96 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-7] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native98 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-9] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native97 started.2018-03-25 21:23:07.664 INFO 4668 --- [ MyExecutor-11] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native99 started.2018-03-25 21:23:07.664 INFO 4668 --- [ main] com.laojiao.securitydemo.ControllerTest : All tasks finished.2018-03-25 21:23:07.666 INFO 4668 --- [ MyExecutor-23] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native71 started.2018-03-25 21:23:07.667 INFO 4668 --- [ MyExecutor-24] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native72 started.2018-03-25 21:23:07.667 INFO 4668 --- [ MyExecutor-25] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native73 started.2018-03-25 21:23:07.669 INFO 4668 --- [ MyExecutor-26] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native74 started.2018-03-25 21:23:07.669 INFO 4668 --- [ MyExecutor-27] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native75 started.2018-03-25 21:23:07.673 INFO 4668 --- [ MyExecutor-28] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native76 started.2018-03-25 21:23:07.674 INFO 4668 --- [ MyExecutor-29] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native77 started.2018-03-25 21:23:07.674 INFO 4668 --- [ MyExecutor-30] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native78 started.2018-03-25 21:23:07.676 INFO 4668 --- [ MyExecutor-31] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native79 started.2018-03-25 21:23:07.677 INFO 4668 --- [ MyExecutor-32] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native80 started.2018-03-25 21:23:07.677 INFO 4668 --- [ MyExecutor-33] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native81 started.2018-03-25 21:23:07.677 INFO 4668 --- [ MyExecutor-34] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native82 started.2018-03-25 21:23:07.678 INFO 4668 --- [ MyExecutor-35] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native83 started.2018-03-25 21:23:07.679 INFO 4668 --- [ MyExecutor-36] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native84 started.2018-03-25 21:23:07.679 INFO 4668 --- [ MyExecutor-37] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native85 started.2018-03-25 21:23:07.679 INFO 4668 --- [ MyExecutor-38] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native86 started.2018-03-25 21:23:07.680 INFO 4668 --- [ MyExecutor-39] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native87 started.2018-03-25 21:23:07.680 INFO 4668 --- [ MyExecutor-40] c.l.securitydemo.mythreadpool.AsyncTask : Task2-Native88 started.作者:PlayInJava 链接:https://juejin.cn/post/6844903584857849870 Git 拉取远程分支代码并合并到本地分支 https://blog.mostion.com/archives/46/ 2023-11-16T16:20:00+08:00 1. 使用git fetch命令需要在本地额外新建分支的 :// 查看远程 git remote -v // 获取远程指定分支到本地临时新建的分支 // 获取远程master的分支的代码到临时新建的temp git fetch origin master:temp // 查看版本差异 // 查看temp分支与当前分支的差异 git diff temp // 将临时分支temp合并到当前分支 git merge tmep // 删除临时分支 git branch -D temp不要在本地新建分支的 :// 查看远程 git remote -v // 获取远程分支到本地 // 获取远程的master分支 git fetch origin master // 查看版本差异 // 查看远程master分支与本地master分支的差别 git log -p master..origin/master // 合并到本地分支 git merge origin/master2.使用git pull命令相当于git fetch与git merge一起使用,但是这样使用容易出错所以推荐第一种方式// 查看远程 git remote -v // 拉取并合并到本地分支 // 拉取远程的master分支合并到当前分支 git pull origin master CentOS yum 安装lnmp相关配置 https://blog.mostion.com/archives/36/ 2023-11-09T13:18:21+08:00 查看系统版本cat /etc/os-release cat /etc/redhat-release rpm -q centos-release查看内核uname -a安装epelyum -y install epel-release rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7安装remi#remi源需要手动启用 rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi yum install -y yum-utils yum-config-manager --enable remi > /dev/null安装php71#!/bin/bash yum -y install \ openssl \ openssl-devel \ libmcrypt \ libmcrypt-devel \ php71 \ php71-php \ php71-php-gd \ php71-php-mysqlnd \ php71-php-mcrypt \ php71-php-imap \ php71-php-ldap \ php71-php-mbstring \ php71-php-pear \ php71-php-xml \ php71-php-xmlrpc \ php71-php-soap \ php71-php-bcmath \ php71-php-mcrypt \ php71-php-fpm \ php71-php-pecl-http \ php71-php-pecl-redis \ php71-php-opcache \ php71-php-pecl-zip //phpexcel 必须#!/bin/bash yum -y install \ openssl \ openssl-devel \ libmcrypt \ libmcrypt-devel \ php74 \ php74-php \ php74-php-gd \ php74-php-mysqlnd \ php74-php-mcrypt \ php74-php-imap \ php74-php-ldap \ php74-php-mbstring \ php74-php-pear \ php74-php-xml \ php74-php-xmlrpc \ php74-php-soap \ php74-php-bcmath \ php74-php-mcrypt \ php74-php-fpm \ php74-php-pecl-http \ php74-php-pecl-redis \ php74-php-opcache \ php74-php-pecl-zip //phpexcel 必须 yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php71 php71-php php71-php-gd php71-php-mysqlnd php71-php-mcrypt php71-php-imap php71-php-ldap php71-php-mbstring php71-php-pear php71-php-xml php71-php-xmlrpc php71-php-soap php71-php-bcmath php71-php-mcrypt php71-php-fpm php71-php-pecl-http php71-php-pecl-redis php71-php-opcache php71-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php72 php72-php php72-php-gd php72-php-mysqlnd php72-php-mcrypt php72-php-imap php72-php-ldap php72-php-mbstring php72-php-pear php72-php-xml php72-php-xmlrpc php72-php-soap php72-php-bcmath php72-php-mcrypt php72-php-fpm php72-php-pecl-http php72-php-pecl-redis php72-php-opcache php72-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php73 php73-php php73-php-gd php73-php-mysqlnd php73-php-mcrypt php73-php-imap php73-php-ldap php73-php-mbstring php73-php-pear php73-php-xml php73-php-xmlrpc php73-php-soap php73-php-bcmath php73-php-mcrypt php73-php-fpm php73-php-pecl-http php73-php-pecl-redis php73-php-opcache php73-php-pecl-zip php73-php-pecl-redis4 php73-php-phalcon4yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php80 php80-php php80-php-gd php80-php-mysqlnd php80-php-mcrypt php80-php-imap php80-php-ldap php80-php-mbstring php80-php-pear php80-php-xml php80-php-xmlrpc php80-php-soap php80-php-bcmath php80-php-mcrypt php80-php-fpm php80-php-pecl-http php80-php-opcache php80-php-pecl-zip php80-php-pecl-redis5 php80-php-phalcon4#修改yum设置,让rpm包缓存到本地 vi /etc/yum.conf #修改keepcache为1 keepcache=1 #清空yum缓存 yum clean all #安装你要离线安装的rpm包 yum install xxx.rpm -y #rpm包缓存到了/var/cache/yum下面 cd /var/cache/yum find ./ -name *.rpm #找到你的rpm包,并拷走就可以离线安装了安装php56#!/bin/bash yum -y install \ libmcrypt \ libmcrypt-devel \ # libjpeg* \ php56 \ php56-php \ php56-php-gd \ php56-php-mysqlnd \ php56-php-mcrypt \ php56-php-imap \ php56-php-ldap \ php56-php-mbstring \ php56-php-pear \ php56-php-xml \ php56-php-xmlrpc \ php56-php-soap \ php56-php-bcmath \ php56-php-mcrypt \ php56-php-fpm \ php56-php-pecl-http \ php56-php-pecl-redis \ php56-php-opcache# 查看某个包的信息 yum --enablerepo=epel info htop # 列出epel信息 yum --disablerepo="*" --enablerepo="epel" list available | less安装MySQL访问地址 下载对应的rpm包http://dev.mysql.com/downloads/repo/yum/安装源wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm yum localinstall mysql80-community-release-el7-1.noarch.rpm手动启用想要的版本yum -y install mysql-community-server yum -y install mysql-community-client启动服务# 启动服务 systemctl start mysqld # 初始化 mysql_secure_installation初始密码cat /var/log/mysqld.logMySQL 2059错误alter user root@localhost identified by 'password' password expire never; alter user root@localhost identified with mysql_native_password by 'password'; flush privileges;安装开发工具包yum groupinstall "Development Tools" "Development Libraries" yum install gcc gcc-c++ gcc-g77 flex bison \ autoconf automake bzip2-devel zlib-devel \ ncurses-devel libjpeg-devel libpng-devel \ libtiff-devel freetype-devel pam-devel \ openssl-devel libxml2-devel gettext-devel \ pcre-devel系统服务目录/usr/lib/systemd/system/ #RPM包安装时分发的unit文件 /run/systemd/system/ #systemd运行时创建的文件 /etc/systemd/system/ #systemctl enable创建的unit文件Linux Headersredhat系列sudo yum -y install kernel-headers //安装kernel-headers sudo yum -y install kernel-devel //安装kernel-develdebian系列sudo apt-get install build-essential //install build-essential(optional) sudo apt-get update //install linux-headers sudo apt-get install linux-headers-$(uname -r) sudo apt-get update && sudo apt-get install build-essential linux-headers-$(uname -r)#discuz 安全 location ~ /(template|attachment|upload)/.*\.(php|php5|PHP|PHP5)?$ { deny all; } Laravel实现适用于API的分页查询 https://blog.mostion.com/archives/34/ 2023-11-06T08:36:00+08:00 Laravel 实现适用于 API 的分页查询Laravel自带分页查询方法里有一些多余的数据,并不完美适用于我们用来做API的查询。本文旨在通过重写 paginate 解决分页查询针对API接口的的灵活性和适用性。新建BaseModel.php文件,代码如下:<?php namespace App\Http\Model; use Illuminate\Database\Eloquent\Model; use Illuminate\Pagination\Paginator; class BaseModel extends Model{ public $timestamps = false; //重写分页方法,使其更加匹配API的规范 //考虑到性能问题,通常$columns我们不以*号为值。可传入需要查询的字段替代。这里只做演示。无此要求 public function paginate($perPage = null, $columns = ['*'], $page = null, $pageName = 'page'){ $page = $page ?: Paginator::resolveCurrentPage($pageName); $perPage = $perPage ?: $this->model->getPerPage(); $results = ($total = $this->toBase()->getCountForPagination()) ? $this->forPage($page, $perPage)->get($columns) : $this->model->newCollection(); $pages = ceil($total / $perPage); $result = ['total'=>$total,'current_page'=>$page,'page_size'=>$perPage,'pages'=>$pages,'list'=>$results]; return $result; } } 然后在业务模型继承此类即可,范例如下:<?php namespace App\Http\Model; class MsgBoard extends BaseModel{ protected $table = 'msg_board'; public function getMsgPageList($page,$pageSize){ return $this->paginate($pageSize, ['*'], $page, 'page'); } } 然后在控制器当中调用即可。范例如下:$page = $request->input('page',1); $pageSize = $request->input('pageSize',12); $msgList = $mMsgBoard->getMsgPageList($page,$pageSize);THE END; php-fpm 调优和配置 https://blog.mostion.com/archives/33/ 2023-11-05T09:08:20+08:00 知识点一般 php-fpm 进程占用20~30m左右的内存就按30m算。如果单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,由于大家一般Nginx、MySQL都在一台机器上,于是预留一半给它们,即php-fpm进程数(max_children)为$Mem/2/30。max_requests:指一个php-fpm的工作进程在处理多少个请求后就终止掉。这个用来处理因为PHP解析器或引用的第三方库时,造成的内存泄露问题。一般原则是:动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗常用命令查看当前php-fpm总进程数,命令:ps -ylC php-fpm --sort:rss 。其中RSS就是占用的内存情况查看当前php-fpm进程的内存占用情况及启动时间,命令如下:ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5查看当前php-fpm进程平均占用内存情况:ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'配置详解:pid = /usr/local/var/run/php-fpm.pid #pid设置,一定要开启,上面是Mac平台的。默认在php安装目录中的var/run/php-fpm.pid。比如centos的在: /usr/local/php/var/run/php-fpm.pid error_log = /usr/local/var/log/php-fpm.log #错误日志,上面是Mac平台的,默认在php安装目录中的var/log/php-fpm.log,比如centos的在: /usr/local/php/var/log/php-fpm.log log_level = notice #错误级别. 上面的php-fpm.log纪录的登记。可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice. emergency_restart_threshold = 60 emergency_restart_interval = 60s #表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。0 表示 '关闭该功能'. 默认值: 0 (关闭). process_control_timeout = 0 #设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0. daemonize = yes #后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。 listen = 127.0.0.1:9000 #fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置。如果nginx和php在不同的机器上,分布式处理,就设置ip这里就可以了。 listen.backlog = -1 #backlog数,设置 listen 的半连接队列长度,-1表示无限制,由操作系统决定,此行注释掉就行。backlog含义参考:http://www.3gyou.cc/?p=41 listen.allowed_clients = 127.0.0.1 #允许访问FastCGI进程的IP白名单,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接。 listen.owner = www listen.group = www listen.mode = 0666 #unix socket设置选项,如果使用tcp方式访问,这里注释即可。 user = www group = www #启动进程的用户和用户组,FPM 进程运行的Unix用户, 必须要设置。用户组,如果没有设置,则默认用户的组被使用。 pm = dynamic #php-fpm进程启动模式,pm可以设置为static和dynamic和ondemand #如果选择static,则进程数就数固定的,由pm.max_children指定固定的子进程数。 #如果选择dynamic,则进程数是动态变化的,由以下参数决定: pm.max_children = 50 #子进程最大数 pm.start_servers = 2 #启动时的进程数,默认值为: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.min_spare_servers = 1 #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程 pm.max_spare_servers = 3 #,保证空闲进程数最大值,如果空闲进程大于此值,此进行清理 pm.max_requests = 500 #设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0. pm.status_path = /status #FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. munin监控会使用到 ping.path = /ping #FPM监控页面的ping网址. 如果没有设置, 则无法访问ping页面. 该页面用于外部检测FPM是否存活并且可以响应请求. 请注意必须以斜线开头 (/)。 ping.response = pong #用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong. access.log = log/$pool.access.log #每一个请求的访问日志,默认是关闭的。 access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" #设定访问日志的格式。 slowlog = log/$pool.log.slow #慢请求的记录日志,配合request_slowlog_timeout使用,默认关闭 request_slowlog_timeout = 10s #当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off' request_terminate_timeout = 0 #设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。 rlimit_files = 1024 #设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 rlimit_core = 0 #设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值. chroot = #启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用. chdir = #设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时) catch_workers_output = yes #重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 默认值: 空.