首页 文章 精选 留言 我的

精选列表

搜索[HTAP架构],共10000篇文章
优秀的个人博客,低调大师

YARN-架构

标签(空格分隔): 大数据 YARN [toc] 原文:http://hadoop.apache.org/docs/r2.6.4/hadoop-yarn/hadoop-yarn-site/YARN.html Hadoop下一代MapReduce(YARN) MapReduce在hadoop-0.23中经历了完整的革新,也就是引入了MapReduce 2.0(MRv2),俗称YARN。 MRv2的核心思想是将原来JobTracker的两个主要功能拆分,也就是将资源管理(resource management)和调度与监控(scheduling/monitoring)分离为两个daemon进程。其思想表现为持有一个全局的ResourceManager(RM)以及每个应用有一个ApplicationMaster(AM)。一个应用对应一个传统的MR

优秀的个人博客,低调大师

HDFS的架构

主从结构 主节点,只有一个: namenode 从节点,有很多个: datanodes 在版本1中,主节点只有一个,在 版本2中主节点有两个。 namenode 负责(管理): 接收用户操作请求 维护文件系统的目录结构 管理文件与 block 之间的关系, block 与 datanode 之间关系 block 是 文件分成的 块, hdfs 中默认的 block 块的大小是64M ,实际的文件肯定会分很多块存储。 datanode 负责(存储): 存储文件 文件被分成 block 存储在磁盘上 为了保证数据安全,文件会有多个副本 在MapReduce 执行计算任务的时候,计算任务的节点。 Hadoop 在存储文件的时候,文件会有多个副本。 因为 Hadoop 是分布式的存储与计算平台,他使用的是廉价的服务器,廉价的服务器可能会发生故障,如果发生故障了,那么数据就不能用了, hadoop 为了提高系统的安全性,对数据进行了冗余存储, 默认情况下数据的副本 是 3. 比如 10G的电影,实际在HDFS中存放的大小不是10G ,而是 30G 。 而在具体数据访问的时候,namenode 会根据不同的 datanode 具体的状况,这种状况包括 他的存储空间、繁忙情况、内存等等从三个副本中选出一个副本去使用 , 另外两个副本就是空闲状态。当这个副本出现问题的时候就会切换到另外一个副本。当然切换回去之后,这个出问题的副本可以得到恢复(与其他副本同步)。 从客户端(java、命令端、其他语言开发的终端….)提交的数据到 namenode , namenode 这时就会看整个集群中的 datanode 中谁属于空闲,谁可用,都会有自己的算法 (关于算法可以从源码的方向上进行理解), 然后确定把数据存储在哪几台机器上,然后 这些客户端就会直接和这些 datanodes打交道,把数据直接交给具体的数据节点。当然数据节点在存储数据的过程中,肯定会有一些日志信息(管理与block之间的关系、block与datanode之间的关系),每一次集群启动的时候,datanode都会把元数据信息(关于 datanode内部怎么组织的)报告给 namenode, 这样namenode 才能知道 datanode 具体是怎么组织的 然后才能够管理。开始做,坚持做,重复做

优秀的个人博客,低调大师

MapReduce 的架构

主从结构 主节点,只有一个 : JobTracker ,JobTracker 一般情况下,运行在 namenode 这台机器上。 从节点,有很多个 : TaskTrackers , 部署在剩下的 datanode 上。 这里谈的 JobTracker 、TaskTrackers 都是 JVM。 JobTracker 负责: 接收客户提交的计算任务 计算任务: 肯定是一段代码---你要怎么操作我的数据。 把计算任务分给TaskTrackers 执行 监控TaskTracker的执行情况 我把任务分配给你了,能否分配成功?失败怎么办?工作的进度?工作的结果? 如果出现了这些问题,MapReduce都会透明的帮我们解决掉这些问题。假如被分配到任务的 TaskTracker 不能够 顺利的完成任务,JobTracker会透明的把任务切换到 另外一台虚拟机上。 但是这种 切换 我们是感觉不到的,这就是用框架的好处,我们写 java 的人只需要关注 业务逻辑。 TaskTrackers 负责 : 执行JobTracker分配的计算任务 开始做,坚持做,重复做

优秀的个人博客,低调大师

【架构实战】账户系统架构:资金安全是底线

## 一、账户系统出问题,是真正的灾难 2020年,我们支付系统出现一个严重Bug: - 用户A充值100元 - 系统记录:账户余额+100,但流水记录失败 - 用户A查询余额显示100元 - 但后台对账发现异常:账户余额 ≠ 流水汇总 **更严重的问题:** - 用户B提现100元 - 系统扣减余额成功,但提现记录失败 - 用户B余额显示正确,但钱没到账 **影响:** - 用户投诉 - 资金损失 - 监管风险 - 团队追责 从那以后,我们把账户系统作为最核心的系统来设计,**资金安全是底线**。 --- ## 二、账户系统核心模型 ### 2.1 账户模型 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 账户系统核心模型 │ │ │ │ 用户账户(Account) │ │ ├── 账户ID │ │ ├── 用户ID │ │ ├── 账户类型(余额账户、积分账户、押金账户) │ │ ├── 余额 │ │ ├── 冻结金额 │ │ └── 版本号(乐观锁) │ │ │ │ 账户流水(Transaction) │ │ ├── 流水ID │ │ ├── 账户ID │ │ ├── 业务订单号 │ │ ├── 交易类型(充值、提现、消费、退款) │ │ ├── 交易金额 │ │ ├── 交易前余额 │ │ ├── 交易后余额 │ │ └── 交易时间 │ │ │ └──────────────────────────────────────────────────────────────────┘ ``` ### 2.2 账户表设计 ```sql -- 账户主表 CREATE TABLE account ( id BIGINT PRIMARY KEY AUTO_INCREMENT, account_no VARCHAR(32) NOT NULL COMMENT '账户号', user_id BIGINT NOT NULL COMMENT '用户ID', account_type TINYINT NOT NULL COMMENT '账户类型:1余额 2积分 3押金', balance DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '余额', frozen_amount DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '冻结金额', version INT NOT NULL DEFAULT 0 COMMENT '版本号', status TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1正常 2冻结 3销户', create_time DATETIME NOT NULL, update_time DATETIME NOT NULL, UNIQUE KEY uk_account_no (account_no), UNIQUE KEY uk_user_type (user_id, account_type), INDEX idx_user_id (user_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户主表'; -- 账户流水表 CREATE TABLE account_transaction ( id BIGINT PRIMARY KEY AUTO_INCREMENT, transaction_no VARCHAR(64) NOT NULL COMMENT '流水号', account_no VARCHAR(32) NOT NULL COMMENT '账户号', biz_order_no VARCHAR(64) COMMENT '业务订单号', transaction_type TINYINT NOT NULL COMMENT '交易类型', amount DECIMAL(12,2) NOT NULL COMMENT '交易金额(正数入账,负数出账)', balance_before DECIMAL(12,2) NOT NULL COMMENT '交易前余额', balance_after DECIMAL(12,2) NOT NULL COMMENT '交易后余额', remark VARCHAR(255) COMMENT '备注', create_time DATETIME NOT NULL, UNIQUE KEY uk_transaction_no (transaction_no), INDEX idx_account_no (account_no), INDEX idx_biz_order_no (biz_order_no), INDEX idx_create_time (create_time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户流水表'; ``` --- ## 三、账户核心操作 ### 3.1 充值流程 ```java /** * 充值服务 */ @Service @Slf4j public class RechargeService { @Autowired private AccountMapper accountMapper; @Autowired private TransactionMapper transactionMapper; @Transactional(rollbackFor = Exception.class) public RechargeResult recharge(RechargeRequest request) { // 1. 参数校验 validateRequest(request); // 2. 幂等性检查 if (transactionMapper.existsByBizOrderNo(request.getBizOrderNo())) { return RechargeResult.success("重复充值,已处理"); } // 3. 查询账户 Account account = accountMapper.selectByUserIdAndType( request.getUserId(), AccountType.BALANCE ); if (account == null) { throw new BusinessException("账户不存在"); } // 4. 乐观锁更新余额 BigDecimal balanceBefore = account.getBalance(); BigDecimal balanceAfter = balanceBefore.add(request.getAmount()); int rows = accountMapper.updateBalance( account.getId(), balanceAfter, account.getVersion() ); if (rows == 0) { throw new BusinessException("余额更新失败,请重试"); } // 5. 记录流水 Transaction transaction = new Transaction(); transaction.setTransactionNo(generateTransactionNo()); transaction.setAccountNo(account.getAccountNo()); transaction.setBizOrderNo(request.getBizOrderNo()); transaction.setTransactionType(TransactionType.RECHARGE); transaction.setAmount(request.getAmount()); transaction.setBalanceBefore(balanceBefore); transaction.setBalanceAfter(balanceAfter); transaction.setRemark("用户充值"); transactionMapper.insert(transaction); // 6. 发送充值成功事件 eventPublisher.publish(new RechargeSuccessEvent( request.getUserId(), request.getAmount() )); return RechargeResult.success(transaction.getTransactionNo()); } } ``` ### 3.2 提现流程 ```java /** * 提现服务 */ @Service @Slf4j public class WithdrawService { @Autowired private AccountService accountService; @Autowired private TransactionMapper transactionMapper; @Autowired private WithdrawOrderMapper withdrawOrderMapper; @Transactional(rollbackFor = Exception.class) public WithdrawResult withdraw(WithdrawRequest request) { // 1. 参数校验 validateRequest(request); // 2. 查询账户 Account account = accountService.getAccount( request.getUserId(), AccountType.BALANCE ); // 3. 检查余额 if (account.getBalance().compareTo(request.getAmount()) = #{amount} AND status = 1 """) int freezeAmount( @Param("accountNo") String accountNo, @Param("amount") BigDecimal amount ); } ``` ### 4.2 流水记录完整性 ```java /** * 账户流水服务 */ @Service @Slf4j public class TransactionService { /** * 记录交易流水(本地事务内) */ public void recordTransaction( String accountNo, String bizOrderNo, Integer transactionType, BigDecimal amount ) { // 1. 查询账户当前余额 Account account = accountMapper.selectByAccountNo(accountNo); // 2. 计算交易前后余额 BigDecimal balanceBefore = account.getBalance(); BigDecimal balanceAfter = balanceBefore.add(amount); // 3. 记录流水 Transaction transaction = new Transaction(); transaction.setTransactionNo(generateTransactionNo()); transaction.setAccountNo(accountNo); transaction.setBizOrderNo(bizOrderNo); transaction.setTransactionType(transactionType); transaction.setAmount(amount); transaction.setBalanceBefore(balanceBefore); transaction.setBalanceAfter(balanceAfter); transactionMapper.insert(transaction); log.info("记录流水: transactionNo={}, accountNo={}, amount={}", transaction.getTransactionNo(), accountNo, amount); } /** * 生成流水号(全局唯一) */ private String generateTransactionNo() { // 格式:日期(8位) + 机器ID(4位) + 序列号(12位) String date = DateUtil.format(new Date(), "yyyyMMdd"); String machineId = String.format("%04d", machineIdProvider.getMachineId()); String sequence = String.format("%012d", sequenceGenerator.next()); return date + machineId + sequence; } } ``` ### 4.3 账务一致性校验 ```java /** * 账务一致性校验服务 */ @Service @Slf4j public class AccountReconcileService { @Autowired private AccountMapper accountMapper; @Autowired private TransactionMapper transactionMapper; /** * 账务一致性校验 */ @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行 public void reconcile() { log.info("开始账务一致性校验..."); // 1. 查询所有账户 List accounts = accountMapper.selectAll(); for (Account account : accounts) { // 2. 计算流水汇总 BigDecimal sumAmount = transactionMapper.sumAmountByAccountNo( account.getAccountNo() ); // 3. 对比账户余额和流水汇总 if (account.getBalance().compareTo(sumAmount) != 0) { log.error("账务不一致: accountNo={}, balance={}, sumAmount={}", account.getAccountNo(), account.getBalance(), sumAmount); // 4. 记录异常,人工处理 reconcileErrorMapper.insert(new ReconcileError( account.getAccountNo(), account.getBalance(), sumAmount, account.getBalance().subtract(sumAmount) )); // 5. 发送告警 alertService.sendAlert("账务异常", String.format("账户%s余额不一致,差额%.2f", account.getAccountNo(), account.getBalance().subtract(sumAmount))); } } log.info("账务一致性校验完成"); } /** * 账户余额修复(需要审批) */ @Transactional(rollbackFor = Exception.class) public void fixAccountBalance(String accountNo, BigDecimal correctBalance) { Account account = accountMapper.selectByAccountNo(accountNo); // 记录调整流水 BigDecimal adjustAmount = correctBalance.subtract(account.getBalance()); Transaction transaction = new Transaction(); transaction.setTransactionNo(generateTransactionNo()); transaction.setAccountNo(accountNo); transaction.setTransactionType(TransactionType.ADJUST); transaction.setAmount(adjustAmount); transaction.setBalanceBefore(account.getBalance()); transaction.setBalanceAfter(correctBalance); transaction.setRemark("账务修复"); transactionMapper.insert(transaction); // 更新账户余额 accountMapper.updateBalance(account.getId(), correctBalance, account.getVersion()); } } ``` --- ## 五、分布式事务方案 ### 5.1 TCC事务方案 ```java /** * 账户TCC事务 */ @Service public class AccountTccService { /** * Try:冻结余额 */ public boolean tryFreeze(String accountNo, BigDecimal amount) { return accountMapper.freezeAmount(accountNo, amount) > 0; } /** * Confirm:扣减冻结余额 */ public boolean confirmDeduct(String accountNo, BigDecimal amount) { return accountMapper.deductFrozenAmount(accountNo, amount) > 0; } /** * Cancel:解冻余额 */ public boolean cancelFreeze(String accountNo, BigDecimal amount) { return accountMapper.unfreezeAmount(accountNo, amount) > 0; } } /** * 支付TCC事务协调器 */ @Service public class PaymentTccCoordinator { @Autowired private AccountTccService accountTccService; @Autowired private OrderTccService orderTccService; @GlobalTransactional public void pay(Long userId, Long orderId, BigDecimal amount) { // Try阶段 boolean accountTry = accountTccService.tryFreeze(userId, amount); boolean orderTry = orderTccService.tryPay(orderId, amount); if (!accountTry || !orderTry) { throw new BusinessException("Try阶段失败"); } // Confirm阶段(Seata自动提交) // 如果失败,自动执行Cancel } } ``` ### 5.2 本地消息表方案 ```java /** * 本地消息表方案 */ @Service @Slf4j public class LocalMessageService { @Autowired private AccountMapper accountMapper; @Autowired private MessageMapper messageMapper; /** * 充值(本地事务) */ @Transactional(rollbackFor = Exception.class) public void recharge(RechargeRequest request) { // 1. 更新账户余额 accountMapper.updateBalance(...); // 2. 记录流水 transactionMapper.insert(...); // 3. 写入本地消息表(同一事务) LocalMessage message = new LocalMessage(); message.setMessageId(UUID.randomUUID().toString()); message.setTopic("recharge-success"); message.setMessageBody(JSON.toJSONString(request)); message.setStatus(MessageStatus.PENDING); messageMapper.insert(message); } /** * 消息发送任务 */ @Scheduled(fixedDelay = 5000) public void sendMessage() { List messages = messageMapper.selectPending(); for (LocalMessage message : messages) { try { // 发送MQ消息 rocketMQTemplate.send(message.getTopic(), message.getMessageBody()); // 更新状态为已发送 messageMapper.updateStatus(message.getMessageId(), MessageStatus.SENT); } catch (Exception e) { log.error("消息发送失败: {}", message.getMessageId(), e); } } } } ``` --- ## 六、踩坑实录 ### 坑1:余额更新丢失 > **问题**:并发更新余额时,后提交的请求覆盖前一个请求。 **踩坑场景**: - 用户余额100元 - 同时发起两个请求:充值50元、消费30元 - 理想结果:余额120元 - 实际结果:余额可能为80元或150元 **解决方案**:使用乐观锁 ```java @Update(""" UPDATE account SET balance = balance + #{delta}, version = version + 1 WHERE id = #{id} AND version = #{version} """) int updateBalanceWithVersion( @Param("id") Long id, @Param("delta") BigDecimal delta, @Param("version") Integer version ); ``` ### 坑2:流水记录缺失 > **问题**:余额更新成功,但流水记录失败。 **踩坑场景**: 数据库连接池满,流水插入失败,但余额已更新。 **解决方案**:本地事务 + 本地消息表 ```java @Transactional(rollbackFor = Exception.class) public void recharge(RechargeRequest request) { // 同一事务内,要么都成功,要么都失败 accountMapper.updateBalance(...); transactionMapper.insert(...); } ``` ### 坑3:幂等性缺失 > **问题**:同一请求重复处理,导致余额重复增加。 **踩坑场景**: 用户充值请求超时重试,系统处理了两次。 **解决方案**:业务订单号去重 ```java public void recharge(RechargeRequest request) { // 检查是否已处理 if (transactionMapper.existsByBizOrderNo(request.getBizOrderNo())) { return; // 已处理,直接返回 } // 处理充值 ... } ``` ### 坑4:账户并发热点 > **问题**:热门账户(如平台账户)并发量大,成为热点。 **踩坑场景**: 所有用户消费都要扣减平台账户余额,该账户成为热点。 **解决方案**:热点账户分片 ```java // 平台账户分片:account_0, account_1, ..., account_9 String accountNo = "platform_" + (userId % 10); // 查询时汇总 BigDecimal totalBalance = accountMapper.sumBalance("platform_*"); ``` ### 坑5:对账数据量大 > **问题**:历史流水数据量大,对账性能差。 **解决方案**:T+N对账 + 分区表 ```sql -- 流水表按月分区 CREATE TABLE account_transaction_202401 ( ... ) ENGINE=InnoDB; -- 只对最近7天数据对账 SELECT * FROM account_transaction WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY); ``` --- ## 七、最佳实践 ### 7.1 账户系统安全检查清单 ``` 账户系统安全检查清单: □ 余额更新 □ 使用乐观锁或悲观锁 □ 本地事务保证原子性 □ 流水记录在同一事务 □ 流水记录 □ 每笔交易都有流水 □ 流水记录余额变化前后值 □ 流水号全局唯一 □ 幂等性 □ 业务订单号去重 □ 流水号唯一索引 □ 对账机制 □ T+1日终对账 □ 余额 = 流水汇总 □ 异常自动告警 □ 安全审计 □ 所有操作有日志 □ 敏感操作有审批 □ 数据变更有记录 ``` --- ## 八、总结 账户系统核心要点: | 要点 | 说明 | |------|------| | 原子性 | 余额更新和流水记录同一事务 | | 一致性 | 余额 = 流水汇总,每日对账 | | 幂等性 | 业务订单号去重 | | 可追溯 | 所有操作有记录 | | 安全性 | 敏感操作有审批 | **血的教训:** > 资金安全是底线。账户系统出问题,不是丢数据,是丢信任。 --- *个人观点,仅供参考*

优秀的个人博客,低调大师

LNMP架构(架构介绍,mysql安装,php安装,nginx介绍)

一、LNMP建构介绍 和LAMP不同的是,提供web服务的是Nginx 并且php是作为一个独立服务存在的,这个服务叫做php-fpm Nginx直接处理静态文件请求,动态请求会转发给php-fpm apache和nginx的区别;https://www.cnblogs.com/huangye-dream/p/3550328.html nginx相对于apache的优点: 轻量级,同样起web 服务,比apache 占用更少的内存及资源抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能高度模块化的设计,编写模块相对简单社区活跃,各种高性能模块出品迅速啊 apache 相对于nginx 的优点:rewrite ,比nginx 的rewrite 强大模块超多,基本想到的都可以找到少bug ,nginx 的bug 相对较多 异步和同步: 同步:你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。 异步:书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。 阻塞和非阻塞: 你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。 在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。 二、mysql的安装 [root@lnmp mysql]# cd /usr/local/src/ [root@lnmp mysql]# wgethttp://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz [root@lnmp mysql]# tar zxvf mysql-5.6.36-linux-glibc2.5-x86_64.tar.gz (解压mysql tar包) [root@lnmp mysql]# mv mysql-5.6.36-linux-glibc2.5-x86_64 /usr/local/mysql (移动解压包并改名) [root@lnmp mysql]# mkdir /data (创建储存的/data目录) [root@lnmp mysql]# useradd mysql (创建mysql用户) [root@lnmp mysql]# vim /etc/my.cnf (修改/etc/my.cnf文件) datadir=/data/mysql socket=/tmp/mysql.sock [root@lnmp mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql (初始化MySQL,并且指定用户和数据库目录,第一次安装时会报错,安装下面2个包就好) [root@lnmp mysql]# yum install autoconf -y [root@lnmp mysql]# yum install -y libaio [root@lnmp mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql [root@lnmp mysql]# cp support-files/mysql.server /etc/init.d/mysqld (复制启动脚本) [root@lnmp mysql]# vim /etc/init.d/mysqld (修改启动脚本里的basedir和datadir) 46 basedir=/usr/local/mysql 47 datadir=/data/mysql [root@lnmp mysql]# /etc/init.d/mysqld start (启动mysql) [root@lnmp mysql]# chkconfig --add mysqld (添加mysql到服务列表) [root@lnmp mysql]# chkconfig mysqld on (设置MySQL开机启动) 添加到服务列表后,就可以使用以下命令: [root@lnmp mysql]# service mysqld stop (启动MySQL) Shutting down MySQL.. SUCCESS! [root@lnmp mysql]# service mysqld start (关闭MySQL) Starting MySQL. SUCCESS! 三、PHP安装 [root@lnmp ~]#cd /usr/local/src (把源码包下载到指定目录) [root@lnmp ~]#wgethttp://cn2.php.net/distributions/php-5.6.30.tar.gz [root@lnmp ~]#tar zxf php-5.6.30.tar.gz [root@lnmp ~]# useradd -s /sbin/nologin php-fpm (添加php-fpm用户,-s指定不能登录) [root@lnmp ~]# cd php-5.6.30 [root@lnmp ~]# ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl --with-openssl (编译php包,过程中可能有需要安装的包,导致的错误) [root@lnmp ~]# make && make install [root@lnmp ~]# cp php.ini-production /usr/local/php-fpm/etc/php.ini (复制目录并改名字) [root@lnmp ~]# vi /usr/local/php/etc/php-fpm.conf (修改php配置文件,以下内容) [global] 定义全局参数 pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] 一个模块的名字 listen = /tmp/php-fcgi.sock 监听的地址 listen.mode = 666 定义sock文件的权限 user = php-fpm 用户 group = php-fpm 用户组 pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 rlimit_files = 1024 [root@lnmp ~]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm (复制启动脚本到以下位置) [root@lnmp ~]# chmod 755 /etc/init.d/php-fpm [root@lnmp ~]# chkconfig --add php-fpm (添加php到服务) [root@lnmp ~]# chkconfig php-fpm on (设置开机启动php服务) [root@lnmp ~]# service php-fpm start (启动php服务) 四、nginx的介绍 •Nginx官网 nginx.org,最新版1.13,最新稳定版1.12 •Nginx应用场景:web服务、反向代理、负载均衡 •Nginx著名分支,淘宝基于Nginx开发的Tengine,使用上和Nginx一致,服务名,配置文件名都一样,和Nginx的最大区别在于Tenging增加了一些定制化模块,在安全限速方面表现突出,另外它支持对js,css合并 •Nginx核心+lua相关的组件和模块组成了一个支持lua的高性能web容器openresty 参考http://jinnianshilongnian.iteye.com/blog/2280928 本文转自 小新锐 51CTO博客,原文链接:http://blog.51cto.com/13407306/2056617,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册