Table of Contents
一、项目环境
二、缘起
三、牛刀小试
四、完美之路
五、面对现实
六、继续探索
Home Backend Development PHP Tutorial 对PHP项目在Docker上运行的一些探索

对PHP项目在Docker上运行的一些探索

Jun 23, 2016 pm 01:16 PM

Docker出现后,容器技术在互联网领域得到了空前的普及,无论是大公司还是屌丝创业公司的码农基本上都会在各种技术社区或者各种演讲会议上了解到过相关技术,我们作为一家屌丝创业公司也不例外,去年对Docker做了一番了解,并在年前测试了一些方案,今天在这里总结一下遇到的各种坑以及踩坑过程中的一些思考,希望能对了解过Docker并且跃跃欲试的同学有点启发,当然更欢迎在这方面有丰富经验的同学给一些建议或者指点。

这篇文章不会提及Docker的理论知识或者基本概念相关的内容,如果想了解Docker的基本使用,Docker的 官方文档 是个不错的选择,如果想了解基本的理论,可以参考下coolshell博客上的几篇文章: Docker基础技术:Linux Namespace(上) 、 Docker基础技术:Linux Namespace(下) 、 Docker基础技术:Linux CGroup 、 Docker基础技术:AUFS 、 Docker基础技术:DeviceMapper 。

一、项目环境

我们项目用的标准的PHP技术栈:PHP-FPM + Nginx,运行在阿里云的ECS上,数据库也是阿里云的服务。

二、缘起

对于一个普通的屌丝创业公司的屌丝项目来说,理论上来说是没必要用太复杂的技术的,对新技术的克制也是码农的一个职业操守。然而我之所以在项目上做这个尝试也并非是想尝试新技术,而是源自于项目上线以来遇到的各种问题,比如前面文章里有提到过的 laravel的性能问题 ,而HHVM或者PHP7这些新技术都大大提到了性能,一下子全部切换风险太大,所以可以用容器来运行某几个服务测试一下;再比如之前有出现过一个BUG,某个接口出现问题占用内存太高导致整个系统响应超时;再比如,看了各种技术大会上别人分享的经验确实想自己试一下,哈哈。

三、牛刀小试

根据Docker的理念,每个容器都是一个独立的服务,服务之间通过接口相互协作。我们采用的方案是PHP-FPM和Nginx分别跑在不同的容器中,PHP-FPM容器暴露端口给Nginx容器。

容器之间的网络通信最初用的是Docker自带的link,link虽然很简单,但是不太好用,link是通过在容器启动时修改/etc/hosts文件来实现的,当时用的时候遇到的一个问题是被link的容器重启后,这个容器IP变了,但是link的容器里并没有更新(1.10版本对link机制做了修改,不知道是否解决了这个问题,还没具体看),还有一个问题就是当同一个服务需要开多个容器时就搞不定了,当然如果是用集群的方式来跑就更搞不定了,所以link只能在本地开发时玩玩,在生产环境没啥用。最后这部分用的方案是用consul来做服务发现,关于consul就不在这里展开介绍了,有兴趣的同学可以看下这篇文章: Service Discovery for Docker Containers using Consul and Registrator 。

然后代码是放在host上,在容器启动时挂载一下代码的目录。根据接口使用的场景将接口分到了几个不同的容器里面去跑,对资源隔离做了下压力测试,符合预期,很满意!然后选了两个容器跑HHVM测试了下,确实性能提高了很多。整个结构如下图所示:

这样可以正常使用了,然后就是日志的处理,最开始挂载了一个host上的目录用来存放日志,但是这样也不太符合Docker的理念,于是就又弄了个logstash容器,将各种容器的日志写到logstash容器里面去。

然后就是对容器的监控,我们用了oneapm提供的服务,还不错,也有其他一些开源工具的选择,但是用oneapm的服务更方便一些。

一个完整的技术栈就这样搞定了,跑了几天也没出现什么问题。作为一个有追求的码农,当然是要有更高的要求的,后来想到这样一个问题:Docker的理念是容器即是一个完整的服务,但是我们的用法是把在容器内把PHP-FPM跑起来了,代码并不在里面,而是通过目录挂载的方式来实现的,这样就需要在host上面部署好代码,没有完美的实现容器即服务的理念。好,我们追求下完美!

四、完美之路

其实把代码放进容器并不只是为了去追求理念上的完美,还有另外一个用意,那就是基于Docker的CI。基本思路是每次发布都会build一个新版本的镜像,build过程中需要把代码更新到最新版本,然后安装依赖的第三方库以及其他一些业务相关的预处理,build完成后再push到registry,然后在各个节点pull下来,重启容器。整个流程如下图所示:

怎么样?这下完美了吧!如果现实也是那么完美就好了,但是偏偏现实总是会有各种各样的坑等着你!

首先,在没有用这个机制之前,发布一次代码也就几秒钟的事情,merge下分支,然后各个节点pull下代码就可以了,但是用了Docker后,merge分支后就需要build一下镜像,build后再push到registry,然后再到各个节点把镜像pull下来,少说也是要花分钟级别的。这时候有的同学可能会说Docker镜像的原理不是layer机制么,对,确实是layer,每次build只需要更新需要更新的layer就可以,但是还是没办法做到像git那样只更新那几个文件,至少要更新整个项目的代码目录。

其次,之前只需要更新一下代码就可以了,现在却需要把容器重启一下!本来重启容器是很快的,但是在容器里PHP-FPM跑起来后却很慢,我猜测是在执行docker stop时会发一个SIGTERM的信号到容器里的进程,PHP-FPM在处理SIGTERM信号时会做一些清理工作。一个节点至少有几十个容器,每个容器都重启一下非常耗时!

这样本来很简单的一个发布,用了这个「完美」的机制后却需要好几分钟。虽然整个流程完全自动化,但是确实没必要为了完美的理念做出这样一个妥协。

此外还遇到了另外一个非常奇葩的问题:升级到1.10后,容器启动后经常会遇到端口不通的情况,这时候如果进入到容器里发起一次网络请求,比如ping以下某个IP,端口就会恢复正常。用各种工具调试了很久依然没找出来问题在哪,屌丝创业公司也没精力研究这么高深的问题,只好暂时搁置了。

挣扎了很久,最后又回到了老路子。

五、面对现实

虽然没能理念上完美的方案,但是也要让整套架构更方便的扩展,比如在流量高峰期快速上架节点。得益于云计算近几年的发展,这个问题也比较容易解决。前面提到代码是放在host的一个目录,那么基本上每个host只需要三个条件就能够上线:

  1. 项目代码目录
  2. 安装Docker
  3. 配置好salt-minion(用来更新配置文件)

只需要在购买一台ECS后,做完上面的操作,生成一个系统镜像,需要上线新节点时用这个系统镜像来直接配置服务器即可。节点上线后,启动各个容器,通过前面提到的用consul实现的服务发现机制,自动加入集群。

六、继续探索

后面打算用Docker Swarm来简单做下集群管理,未来对调度需求比较大时可能会尝试下Mesos或者Kubernetes。不过关于容器的生态链都发展的非常快,可能等需要的时候又有更好的方案了吧。

简单总结下整个过程的感悟吧,从架构上来说,永远都没有完美的架构,只有最适合自己的架构。从码农角度来说,在做技术选型时最重要的是权衡当前项目需求、团队对各种技术了解的程度以及该技术选型带来的复杂度。切勿看了几个大牛的技术架构分享就在自己项目上跃跃欲试,最后弄的连自己都搞不定还给别人留下一个烂摊子收拾。最后,在项目迭代过程中保持项目的简单的能力永远是衡量一个码农技术的水平的重要标准。

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1274
29
C# Tutorial
1256
24
Explain secure password hashing in PHP (e.g., password_hash, password_verify). Why not use MD5 or SHA1? Explain secure password hashing in PHP (e.g., password_hash, password_verify). Why not use MD5 or SHA1? Apr 17, 2025 am 12:06 AM

In PHP, password_hash and password_verify functions should be used to implement secure password hashing, and MD5 or SHA1 should not be used. 1) password_hash generates a hash containing salt values ​​to enhance security. 2) Password_verify verify password and ensure security by comparing hash values. 3) MD5 and SHA1 are vulnerable and lack salt values, and are not suitable for modern password security.

PHP and Python: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP in Action: Real-World Examples and Applications PHP in Action: Real-World Examples and Applications Apr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

How does PHP type hinting work, including scalar types, return types, union types, and nullable types? How does PHP type hinting work, including scalar types, return types, union types, and nullable types? Apr 17, 2025 am 12:25 AM

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values ​​and handle functions that may return null values.

The Enduring Relevance of PHP: Is It Still Alive? The Enduring Relevance of PHP: Is It Still Alive? Apr 14, 2025 am 12:12 AM

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP and Python: Different Paradigms Explained PHP and Python: Different Paradigms Explained Apr 18, 2025 am 12:26 AM

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP and Python: Code Examples and Comparison PHP and Python: Code Examples and Comparison Apr 15, 2025 am 12:07 AM

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

How do you prevent SQL Injection in PHP? (Prepared statements, PDO) How do you prevent SQL Injection in PHP? (Prepared statements, PDO) Apr 15, 2025 am 12:15 AM

Using preprocessing statements and PDO in PHP can effectively prevent SQL injection attacks. 1) Use PDO to connect to the database and set the error mode. 2) Create preprocessing statements through the prepare method and pass data using placeholders and execute methods. 3) Process query results and ensure the security and performance of the code.

See all articles