Confoo talks

This commit is contained in:
Rasmus Lerdorf
2016-02-21 16:36:40 -08:00
parent 0bc5ba3be3
commit 2cd1b96680
14 changed files with 2200 additions and 14 deletions

1271
confoo16.html Normal file

File diff suppressed because it is too large Load Diff

59
confoo16.xml Normal file
View File

@@ -0,0 +1,59 @@
<presentation
template="simple"
navmode="html"
titlecolor="#000000"
navbarbackground="#bbbbbb"
navbartopiclinks="0"
logo1="images/php-med-trans.png"
titlesize="6em"
navbarheight="3.5em"
examplebackground="#ffffff"
outputbackground="#ffffff"
exampleclass="noshadow"
exampleoutputclass="noshadow"
>
<topic>PHP</topic>
<title>Speeding up the Web with PHP 7</title>
<event>Confoo</event>
<location>Montreal</location>
<date>Feb.24, 2016</date>
<speaker>Rasmus Lerdorf</speaker>
<url>http://talks.php.net/confoo16</url>
<twitter>@rasmus</twitter>
<slide>slides/intro/titlepage.xml</slide>
<slide>slides/intro/nold.xml</slide>
<slide>slides/intro/nold2.xml</slide>
<slide>slides/intro/nold3.xml</slide>
<slide>slides/intro/php7_2016.xml</slide>
<slide>slides/intro/perf2014.xml</slide>
<slide>slides/intro/php7_perf.xml</slide>
<slide>slides/intro/benchlies.xml</slide>
<slide>slides/intro/nov3/benchbox.xml</slide>
<slide>slides/intro/nov3/drupalbench.xml</slide>
<slide>slides/intro/nov3/wpbench.xml</slide>
<slide>slides/intro/nov3/bbbench.xml</slide>
<slide>slides/intro/nov3/mwbench.xml</slide>
<slide>slides/intro/nov3/opencartbench.xml</slide>
<slide>slides/intro/nov3/wardrobebench.xml</slide>
<slide>slides/intro/nov3/geeklogbench.xml</slide>
<slide>slides/intro/nov3/magentobench.xml</slide>
<slide>slides/intro/nov3/traqbench.xml</slide>
<slide>slides/intro/nov3/cachetbench.xml</slide>
<slide>slides/intro/nov3/moodlebench.xml</slide>
<slide>slides/intro/nov3/zencartbench.xml</slide>
<slide>slides/intro/smem.xml</slide>
<slide>slides/intro/smembase.xml</slide>
<slide>slides/intro/smemdrupal.xml</slide>
<slide>slides/intro/smemwp.xml</slide>
<slide>slides/intro/smembb.xml</slide>
<slide>slides/intro/smemmoodle.xml</slide>
<slide>slides/intro/smemwardrobe.xml</slide>
<slide>slides/intro/php_contribute_2016.xml</slide>
<slide>slides/intro/thank_you.xml</slide>
</presentation>

681
confoo16a.html Normal file
View File

@@ -0,0 +1,681 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Deploying PHP 7</title>
<meta name="description" content="Deploying PHP 7">
<meta name="author" content="Rasmus Lerdorf">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="/reveal.js/css/reveal.css">
<link rel="stylesheet" href="/reveal.js/css/theme/white.css" id="theme">
<!-- For syntax highlighting - note that these are not the generic highlight.js theme files - see https://github.com/nwinkler/reveal-highlight-themes -->
<link rel="stylesheet" href="/styles/xcode.css">
<!-- Override a few styles -->
<style>
/*
Not actually sure why this block isn't being picked up from the syntax highlight css
If you change the syntax highlight theme, copy the first block here
*/
.reveal pre code {
display: block;
max-height: 600px;
overflow-x: auto;
padding: 0.5em;
line-height: 125%;
background: #fff;
color: black;
-webkit-text-size-adjust: none;
}
.reveal section img {
box-shadow: none;
border: none;
}
.reveal code.shell {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #000;
color: #ddd;
line-height: 125%;
-webkit-text-size-adjust: none;
}
/* Left-align h3 and h4 if they are p elements */
h3.p {
text-align: left;
}
h4.p {
text-align: left;
}
/* and left-aligned but slightly indented bullet lists */
.reveal ul {
display: block;
margin: 0 0 1em 3em;
}
/* Example titles */
p.example {
text-align: left;
margin: 0 0 -0.5em 1em;
font-weight: bold;
}
/* Example output style */
pre.output {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #ddd;
color: black;
line-height: 200%;
-webkit-text-size-adjust: none;
}
</style>
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? '/reveal.js/css/print/pdf.css' : '/reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!-- Needed for charts to work. Fall back to network if no local copy -->
<script type='text/javascript' src='/jquery.min.js'></script>
<script>window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">\x3C/script>')</script>
<script src="/highcharts.js"></script>
<script>window.Highcharts || document.write('<script src="http://code.highcharts.com/highcharts.js">\x3C/script>')</script>
<!--[if lt IE 9]>
<script src="/reveal.js/lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Deploying PHP 7</h1>
<h3>Confoo</h3>
<h3>Montreal</h3>
<h3>Feb.25, 2016</h3>
<a href="http://talks.php.net/confoo16a">http://talks.php.net/confoo16a</a><br><br>
<p>Rasmus Lerdorf<br>
<small><a href="http://twitter.com/@rasmus">@rasmus</a></small>
</p>
<aside class="notes">
</aside>
</section>
<section>
<section id="bc7">
<h1 style="text-align:center;">Top-5 Things that might bite you</h1>
<br/>
<br/>
<br/>
<p class="p" style="font-size:1.5em;text-align:center;">For the full list see</p>
<div align="center" style="font-size: 1.25em; color: ; text-align: center; margin-left: ; margin-right: ; margin-top: -0.75em; margin-bottom: ;"><a href="http://php.net/manual/en/migration70.php" target="">php.net/migration70</a></div>
</section>
<section id="bc7_1">
<p class="p" style="font-size:1.1em;text-align:left;">Left-to-right semantics for complicated expressions</p>
<pre><code class="php" data-trim style="font-size:1.1em;">$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo-&gt;$bar['baz'] // interpreted as ($foo-&gt;$bar)['baz']
$foo-&gt;$bar['baz']() // interpreted as ($foo-&gt;$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">To restore the previous behaviour add explicit curly braces:</p>
<pre><code class="php" data-trim style="font-size:1.1em;">${$foo['bar']['baz']}
$foo-&gt;{$bar['baz']}
$foo-&gt;{$bar['baz']}()
Foo::{$bar['baz']}()</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">Detection: phan or unit test failures</p>
</section>
<section id="bc7_2">
<p class="p" style="font-size:1.1em;text-align:left;">Removed support for /e (PREG_REPLACE_EVAL) modifier</p>
<pre><code class="php" data-trim style="font-size:1.1em;">echo preg_replace('/:-:(.*?):-:/e', '$this-&gt;pres-&gt;\\1', $text);</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">Change to:</p>
<pre><code class="php" data-trim style="font-size:1.1em;">echo preg_replace_callback(
'/:-:(.*?):-:/',
function($matches) {
return $this-&gt;pres-&gt;{$matches[1]}; // Careful!
},
$text);</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">Detection: grep, warnings in logs or unit test failures</p>
</section>
<section id="bc7_3">
<p class="p" style="font-size:1.1em;text-align:left;">$HTTP_RAW_POST_DATA global removed</p>
<pre><code class="php" data-trim style="font-size:1em;">if (empty($GLOBALS['HTTP_RAW_POST_DATA']) &amp;&amp;
strpos($_SERVER['CONTENT_TYPE'], 'www-form-urlencoded') === false) {
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents(&quot;php://input&quot;);
}</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">Detection: grep, warnings in logs or unit test failures</p>
</section>
<section id="bc7_4">
<p class="p" style="font-size:1.1em;text-align:left;">session.lazy_write enabled by default</p>
<pre><code class="ini" data-trim style="font-size:1.1em;">session.lazy_write = 0</code></pre>
<p class="p" style="font-size:0.8em;text-align:left;">Detection: Can cause out-of-band session read timing issues</p>
</section>
<section id="bc7_5">
<p class="p" style="font-size:1.1em;text-align:left;">Invalid octal literals now produce a parse error</p>
<pre><code class="php" data-trim style="font-size:1.1em;">echo 05678; // PHP 5.x outputs 375</code></pre>
<pre class="output" style="font-size:0.5em;">Parse error: Invalid numeric literal in file.php on line 2 </pre> <p class="p" style="font-size:0.8em;text-align:left;">Detecting parse errors is easy: php -l</p>
</section> </section>
<section>
<section id="phan">
<h1 style="text-align:center;">Static Analysis</h1>
<br/>
<br/>
<br/>
<div align="center" style="font-size: 1.25em; color: ; text-align: center; margin-left: ; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/phan" target="">github.com/etsy/phan</a></div>
</section>
<section id="phan1">
<pre><code class="shell nohighlight" data-trim style="font-size:0.8em;">% phan -h
Usage: ./phan [options] [files...]
-f, --fileset &lt;filename&gt;
A file containing a list of PHP files to be analyzed
-l, --directory &lt;directory&gt;
A directory to recursively read PHP files from to analyze
-3, --exclude-directory-list &lt;dir_list&gt;
A comma-separated list of directories for which any files
therein should be parsed but not analyzed.
-s, --state-file &lt;filename&gt;
Save state to the given file and read from it to speed up
future executions
-r, --reanalyze-file-list &lt;file-list&gt;
Force a re-analysis of any files passed in even if they haven't
changed since the last analysis
-d, --project-root-directory
Hunt for a directory named .phan in the current or parent
directory and read configuration file config.php from that
path.
-m &lt;mode&gt;, --output-mode
Output mode: text, codeclimate
-o, --output &lt;filename&gt;
Output filename
-p, --progress-bar
Show progress bar
-a, --dump-ast
Emit an AST for each file rather than analyze
-q, --quick
Quick mode - doesn't recurse into all function calls
-b, --backward-compatibility-checks
Check for potential PHP 5 -&gt; PHP 7 BC issues
-i, --ignore-undeclared
Ignore undeclared functions and classes
-y, --minimum-severity &lt;level in {0,5,10}&gt;
Minimum severity level (low=0, normal=5, critical=10) to report.
Defaults to 0.
-c, --parent-constructor-required
Comma-separated list of classes that require
parent::__construct() to be called
-x, --dead-code-detection
Emit issues for classes, methods, functions, constants and
properties that are probably never referenced and can
possibly be removed.
-h,--help
This help information</code></pre>
</section>
<section id="phan2">
<pre><code class="shell nohighlight" data-trim style="font-size:0.8em;">% phan -i -b display.php
display.php:416 CompatError expression may not be PHP 7 compatible</code></pre>
<pre><code data-trim style="font-size:1em;">echo preg_replace('/:-:(.*?):-:/e', '$this-&gt;pres-&gt;\\1', $text);</code></pre>
<pre><code data-trim style="font-size:1em;">echo preg_replace_callback(
'/:-:(.*?):-:/',
function($matches) {
return $this-&gt;pres-&gt;$matches[1]; // Oops!
},
$text);</code></pre>
<pre><code data-trim style="font-size:1em;">echo preg_replace_callback(
'/:-:(.*?):-:/',
function($matches) {
return $this-&gt;pres-&gt;{$matches[1]}; // Ok
},
$text);</code></pre>
</section>
<section id="phan3">
<pre><code class="shell nohighlight" data-trim style="font-size:0.8em;">% git clone https://github.com/Seldaek/monolog.git
% cd monolog
% find . -name '*.php' | grep -v test &gt; filelist.txt
% phan -i -b -f filelist.txt
./src/Monolog/ErrorHandler.php:167 PhanTypeMismatchProperty Assigning null to property but \Monolog\errorhandler::reservedMemory is string
./src/Monolog/Formatter/GelfMessageFormatter.php:60 PhanTypeMismatchProperty Assigning null to property but \Monolog\Formatter\gelfmessageformatter::extraPrefix is string
./src/Monolog/Formatter/NormalizerFormatter.php:62 PhanTypeMismatchArgumentInternal Argument 1 (val) is array but \is_infinite() takes float
./src/Monolog/Formatter/NormalizerFormatter.php:65 PhanTypeMismatchArgumentInternal Argument 1 (val) is array but \is_nan() takes float
./src/Monolog/Formatter/NormalizerFormatter.php:98 PhanTypeMismatchArgumentInternal Argument 1 (object) is array but \method_exists() takes object|string
./src/Monolog/Formatter/NormalizerFormatter.php:99 PhanNonClassMethodCall Call to method __toString on non-class type array
./src/Monolog/Formatter/NormalizerFormatter.php:105 PhanTypeMismatchArgumentInternal Argument 1 (object) is array but \get_class() takes object
./src/Monolog/Handler/ChromePHPHandler.php:178 PhanTypeMismatchReturn Returning type int but headersAccepted() is declared to return bool
./src/Monolog/Handler/ElasticSearchHandler.php:124 PhanTypeMismatchArgumentInternal Argument 3 (previous) is \Elastica\Exception\exceptioninterface but \runtimeexception::__construct() takes \runtimeexception|\throwable
./src/Monolog/Handler/FirePHPHandler.php:81 PhanTypeMismatchReturn Returning type array but createRecordHeader() is declared to return string
./src/Monolog/Handler/FirePHPHandler.php:153 PhanTypeMismatchArgumentInternal Argument 1 (array_arg) is string but \current() takes array
./src/Monolog/Handler/FirePHPHandler.php:154 PhanTypeMismatchArgumentInternal Argument 1 (array_arg) is string but \current() takes array
./src/Monolog/Handler/FirePHPHandler.php:154 PhanTypeMismatchArgumentInternal Argument 1 (array_arg) is string but \key() takes array
./src/Monolog/Handler/FlowdockHandler.php:70 PhanTypeMissingReturn Method \Monolog\Handler\flowdockhandler::getdefaultformatter is declared to return \Monolog\Formatter\formatterinterface but has no return value
./src/Monolog/Handler/GelfHandler.php:55 PhanTypeMismatchProperty Assigning null to property but \Monolog\Handler\gelfhandler::publisher is \Gelf\imessagepublisher|\Gelf\publisher|\Gelf\publisherinterface
./src/Monolog/Handler/RedisHandler.php:41 PhanTypeMismatchDefault Default value for int $capSize can't be bool
./src/Monolog/Handler/SocketHandler.php:115 PhanTypeMismatchProperty Assigning float to property but \Monolog\Handler\sockethandler::timeout is int
./src/Monolog/Handler/SocketHandler.php:126 PhanTypeMismatchProperty Assigning float to property but \Monolog\Handler\sockethandler::writingTimeout is int
./src/Monolog/Handler/SocketHandler.php:218 PhanTypeMismatchArgumentInternal Argument 2 (seconds) is float but \stream_set_timeout() takes int
./src/Monolog/Handler/SocketHandler.php:218 PhanTypeMismatchArgumentInternal Argument 3 (microseconds) is float but \stream_set_timeout() takes int
./src/Monolog/Handler/SocketHandler.php:274 PhanTypeMismatchProperty Assigning resource to property but \Monolog\Handler\sockethandler::resource is null
./src/Monolog/Handler/StreamHandler.php:65 PhanTypeMismatchProperty Assigning null to property but \Monolog\Handler\streamhandler::stream is resource|string
./src/Monolog/Handler/StreamHandler.php:86 PhanTypeMismatchProperty Assigning null to property but \Monolog\Handler\streamhandler::stream is resource|string
./src/Monolog/Handler/StreamHandler.php:105 PhanTypeMismatchProperty Assigning array|string to property but \Monolog\Handler\streamhandler::errorMessage is null
./src/Monolog/Handler/SwiftMailerHandler.php:83 PhanTypeMismatchArgument Argument 1 (content) is null but \Monolog\Handler\swiftmailerhandler::buildmessage() takes string defined at ./src/Monolog/Handler/SwiftMailerHandler.php:55
./src/Monolog/Handler/SyslogUdp/UdpSocket.php:38 PhanTypeMismatchProperty Assigning null to property but \Monolog\Handler\SyslogUdp\udpsocket::socket is resource</code></pre>
</section> </section>
<section>
<section id="deploy">
<h1 style="text-align:center;">Let's deploy it!</h1>
</section>
<section id="deploy0">
<p class="p" style="font-size:2em;text-align:left;">Atomic</p>
<p class="p" style="font-size:2em;text-align:left;">No performance hit</p>
<ul>
<li style="font-size: 1.5em;">No restarts</li>
<li style="font-size: 1.5em;">No LB removal</li>
<li style="font-size: 1.5em;">No thundering herd</li>
<li style="font-size: 1.5em;">Cache reuse</li>
</ul>
</section>
<section id="deploy1">
<p class="p" style="font-size:1.1em;text-align:left;">Must be able to serve two versions of the site concurrently!</p>
<img src="/presentations/slides/intro/atomic_deploy1.png" width="" height="">
</section>
<section id="deploy2">
<img src="/presentations/slides/intro/atomic_deploy2.png" width="" height="">
</section>
<section id="deploy3">
<p class="p" style="font-size:1.1em;text-align:left;">Requests that begin on DocumentRoot A must finish on A</p>
</section>
<section id="deploy4">
<p class="p" style="font-size:1.1em;text-align:left;">Set the DocumentRoot to symlink target!</p>
<p class="p" style="font-size:1.1em;text-align:left;">Easy with nginx</p>
<pre><code class="ini" data-trim style="font-size:1.1em;">fastcgi_param DOCUMENT_ROOT $realpath_root</code></pre>
<p class="p" style="font-size:1.1em;text-align:left;">Apache</p>
<div align="left" style="font-size: 1.25em; color: ; text-align: left; margin-left: 1em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/mod_realdoc" target="">github.com/etsy/mod_realdoc</a></div>
</section>
<section id="deploy5">
<p class="p" style="font-size:1.1em;text-align:left;">Avoid hardcoding full paths</p>
<p class="p" style="font-size:1.1em;text-align:left;">Watch your include_path setting</p>
<p class="p" style="font-size:1.1em;text-align:left;">incpath extension can resolve your include_path for you</p>
<div align="left" style="font-size: 1.25em; color: ; text-align: left; margin-left: 1em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/incpath" target="">https://github.com/etsy/incpath</a></div>
</section>
<section id="deploy6">
<p class="p" style="font-size:1.1em;text-align:left;">Version all static assets</p>
<p class="p" style="font-size:1.1em;text-align:left;">DB Schema changes need special care</p>
</section> </section>
<section>
<section id="etsy_deploy">
<h2 style="text-align:center;">How do you manage deploys?</h2>
</section>
<section id="etsy_deploy0">
<p class="p" style="font-size:2em;text-align:left;">At Etsy we use irc</p>
<pre><code class="shell nohighlight" data-trim style="font-size:0.9em;">Channel: #push Topic: &lt;prod&gt; *joe frank|bob
devbot: Swapping symlinks. Your code is about to start taking production traffic
pushbot: joe frank : Your code is live. Time to watch graphs: http://etsy/abcd
Rasmus: .join
*** pushbot has changed the topic on #push to &lt;prod&gt; joe frank|bob Rasmus
frank: .good
*** pushbot has changed the topic on #push to &lt;prod&gt; *joe *frank|bob Rasmus
joe: .done
*** pushbot has changed the topic on #push to &lt;prod&gt; bob Rasmus
pushbot: bob Rasmus: You're up
bob: .in
*** pushbot has changed the topic on #push *bob Rasmus
Rasmus: .in
*** pushbot has changed the topic on #push *bob *Rasmus</code></pre>
</section>
<section id="etsy_deploy1">
<p class="p" style="font-size:2em;text-align:left;">pushbot commands</p>
<ul>
<li style="list-style-type: none;"><strong>.join</strong>    - join push queue</li>
<li style="list-style-type: none;"><strong>.in</strong>        - code has been pushed</li>
<li style="list-style-type: none;"><strong>.good</strong> - your stuff looks good</li>
<li style="list-style-type: none;"><strong>.uhoh</strong> - your stuff looks bad</li>
<li style="list-style-type: none;"><strong>.hold</strong>  - there is a problem, hold everything</li>
<li style="list-style-type: none;"><strong>.nm</strong>     - never mind (leave queue)</li>
<li style="list-style-type: none;"><strong>.done</strong> - push done</li>
</ul>
</section>
<section id="etsy_deploy2">
<img src="/presentations/slides/intro/deployinator.png" width="" height="">
</section>
<section id="etsy_deploy3">
<pre><code class="shell nohighlight" data-trim style="font-size:0.9em;">Channel: #push Topic: &lt;princess&gt; bob Rasmus
Jenkins: Starting build #36803 for job qa
Jenkins: Starting build #38784 for job princess
Jenkins: Project qa build #36803: SUCCESS in 6 min 19 sec: http://ci/job/qa/36803/
pushbot: bob Rasmus : qa tests have passed
devbot: [who_tried] Everyone in this push has run Try recently. w00t!
Jenkins: Project princess build #38784: SUCCESS in 1 min 10 sec: http://ci/job/princess/38784/
pushbot: bob Rasmus : princess tests have passed
bob: .good
Rasmus: .good
*** pushbot has changed the topic on #push to &lt;princess&gt; *bob *Rasmus
pushbot: bob Rasmus : everyone is ready, checking on Jenkins...
Jenkins: qa: last build: 36803 (9 min 5 sec ago): SUCCESS: http://ci/job/qa/36803/
Jenkins: princess: last build: 38784 (2 min 54 sec ago): SUCCESS: http://ci/job/princess/38784/</code></pre>
</section>
<section id="etsy_deploy4">
<p class="p" style="font-size:2.5em;text-align:left;">Deploy to Production:</p>
<ul>
<li style="font-size: 2em;">ssh to deploy host</li>
<li style="font-size: 2em;">dsh to all targets</li>
<li style="font-size: 2em;">rsync files</li>
</ul>
</section>
<section id="etsy_deploy5">
<pre><code class="shell nohighlight" data-trim style="font-size:0.9em;">Channel: #push Topic: &lt;prod&gt; bob Rasmus
devbot: Swapping symlinks. Your code is about to start taking production traffic
pushbot: bob Rasmus : Your code is live. Time to watch graphs: http://etsy/et5cp
Jenkins: Starting build #39452 for job prod
pushbot: bob Rasmus : prod tests have passed
Jenkins: Project prod build #39452: SUCCESS in 30 sec: http://ci/job/prod/39452/
bob: .good
Rasmus: .good
*** pushbot has changed the topic on #push to &lt;prod&gt; *bob *Rasmus
pushbot: bob Rasmus : everyone is ready, checking on Jenkins...
Jenkins: prod: last build: 39452 (1 min 39 sec ago): SUCCESS: http://ci/job/prod/39452/
bob: .done
pushbot: clear
*** pushbot has changed the topic on #push to clear</code></pre>
</section>
<section id="etsy_deploy6">
<p class="p" style="font-size:2.5em;text-align:left;">Graph Everything!</p>
<ul>
<li style="font-size: 2em;">Statsd</li>
<li style="font-size: 2em;">Ganglia</li>
<li style="font-size: 2em;">Graphite</li>
</ul>
</section>
<section id="etsy_deploy7">
<p class="p" style="font-size:2.5em;text-align:left;">Log Everything!</p>
<ul>
<li style="font-size: 2em;">logster</li>
<li style="font-size: 2em;">Supergrep</li>
<li style="font-size: 2em;">Logstash</li>
<li style="font-size: 2em;">Elastic Search</li>
</ul>
</section>
<section id="etsy_deploy8">
<ul>
<li style="font-size: 1.5em;">Commit to master</li>
<li style="font-size: 1.5em;">Deploy from HEAD</li>
<li style="font-size: 1.5em;">Branches?</li>
<li style="font-size: 1.5em;">Branches are in code via feature flags</li>
</ul>
</section>
<section id="etsy_deploy9">
<p class="p" style="font-size:2.5em;text-align:left;">Blameless post-mortems</p>
</section>
<section id="etsy_deploy10">
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/deployinator" target="">github.com/etsy/deployinator</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/statsd" target="">github.com/etsy/statsd</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/logster" target="">github.com/etsy/logster</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/morgue" target="">github.com/etsy/morgue</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/feature" target="">github.com/etsy/feature</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/supergrep" target="">github.com/etsy/supergrep</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/PushBot" target="">github.com/etsy/PushBot</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/etsy/TryLib" target="">github.com/etsy/TryLib</a></div>
</section> </section>
<section>
<section id="prod_perc95">
<h2 margin-bottom="2em">PHP 7 in production</h2><br>
<img src="/presentations/slides/intro/perc95.png" align="center" width="882" height="465">
</section>
<section id="prod_cpu">
<img src="/presentations/slides/intro/cpu.png" align="center" width="882" height="465">
</section>
<section id="prod_mem">
<img src="/presentations/slides/intro/mem.png" align="center" width="882" height="465">
</section> </section>
<section>
<section id="numa">
<h2 margin-bottom="2em">Hyperthreading and NUMA</h2><br>
<ul>
<li style="font-size: 1em;list-style-type: circle;">HyperThreading handles extreme loads better</li>
<li style="font-size: 1em;list-style-type: circle;">If you don't have multi-socket servers, turn on HT and move on</li>
<li style="font-size: 1em;list-style-type: circle;">For multi-socket servers, things get interesting</li>
</ul>
</section>
<section id="numa_singlesocket">
<p class="example">Digital Ocean</p>
<pre><code class="shell nohighlight" data-trim style="font-size:1em;">$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz
Stepping: 2
CPU MHz: 1797.917
BogoMIPS: 3595.83
Virtualization: VT-x
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0,1</code></pre>
</section>
<section id="numa_multisocket">
<p class="example">Multi-socket bare metal without HT</p>
<pre><code class="shell nohighlight" data-trim style="font-size:1em;">$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 24
On-line CPU(s) list: 0-23
Thread(s) per core: 1
Core(s) per socket: 12
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Stepping: 2
CPU MHz: 1203.320
BogoMIPS: 5005.24
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0-11
NUMA node1 CPU(s): 12-23</code></pre>
</section>
<section id="numa_multisocket_ht">
<p class="example">Multi-socket bare metal with HT</p>
<pre><code class="shell nohighlight" data-trim style="font-size:1em;">$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 48
On-line CPU(s) list: 0-47
Thread(s) per core: 2
Core(s) per socket: 12
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Stepping: 2
CPU MHz: 1200.000
BogoMIPS: 5004.73
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0-11,24-35
NUMA node1 CPU(s): 12-23,36-47</code></pre>
</section>
<section id="htop_graphs">
<img src="/presentations/slides/intro/htop_ht.png" align="center" width="800" height="325">
<img src="/presentations/slides/intro/htop.png" align="center" width="979" height="229">
</section>
<section id="numa_graph">
<img src="/presentations/slides/intro/numa_ht.png" align="center" width="979" height="507">
</section>
<section id="numa_solutions">
<br/>
<h4 class="p">Solutions?</h4>
<ul>
<li style="font-size: 1em;list-style-type: circle;">numactl --interleave=all httpd/php-fpm</li>
<li style="font-size: 1em;list-style-type: circle;">split multi-socket with containers</li>
<li style="font-size: 1em;list-style-type: circle;">ignore it</li>
</ul>
</section> </section>
<section>
<section id="driveshaft">
<h2 style="text-align:center;">Using Gearman?</h2>
<h2 style="text-align:center;">Check out Driveshaft!</h2>
<div align="center" style="font-size: 1.2em; color: ; text-align: center; margin-left: ; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/keyurdg/driveshaft" target="">github.com/keyurdg/driveshaft</a></div>
</section>
<section id="driveshaft1">
<ul>
<li style="font-size: 1.5em;">Manages pools of workers</li>
<li style="font-size: 1.5em;">Registers jobs with Gearmand for each pool</li>
<li style="font-size: 1.5em;">Jobs are run by hitting an endpoint over HTTP/S</li>
</ul>
</section>
<section id="driveshaft2">
<pre><code class="json" data-trim style="font-size:1.1em;">{
&quot;gearman_servers_list&quot;:
[
&quot;localhost&quot;
],
&quot;pools_list&quot;:
{
&quot;ShopStats&quot;:
{
&quot;job_processing_uri&quot;: &quot;http://localhost/job.php&quot;,
&quot;worker_count&quot;: 20,
&quot;jobs_list&quot;:
[
&quot;ShopStats&quot;
]
},
&quot;Newsfeed&quot;:
{
&quot;job_processing_uri&quot;: &quot;http://localhost/job.php&quot;,
&quot;worker_count&quot;: 10,
&quot;jobs_list&quot;:
[
&quot;Newsfeed&quot;
]
},
&quot;Regular&quot;:
{
&quot;job_processing_uri&quot;: &quot;http://localhost/job.php&quot;,
&quot;worker_count&quot;: 5,
&quot;jobs_list&quot;:
[
&quot;Sum3&quot;,
&quot;Sum&quot;,
&quot;Sum2&quot;
]
}
}
}</code></pre>
</section> </section>
<section>
<section id="thank_you">
<h2 style="text-align:center;">Thank You</h2>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/rlerdorf/php7dev" target="">https://github.com/rlerdorf/php7dev</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://github.com/rlerdorf/phan" target="">https://github.com/rlerdorf/phan</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href="https://bugs.php.net" target="">https://bugs.php.net</a></div>
<div align="left" style="font-size: 1.2em; color: ; text-align: left; margin-left: 2em; margin-right: ; margin-top: ; margin-bottom: ;"><a href=":-:url:-:" target="">http://talks.php.net/confoo16a</a></div>
<br/>
<br/>
<br/>
<p class="p" style="font-size:1.1em;">Report Bugs</p>
<p class="p" style="font-size:1.1em;">Useful bug reports, please!</p>
</section> </section>
</div>
</div>
<script src="/reveal.js/lib/js/head.min.js"></script>
<script src="/reveal.js/js/reveal.js"></script>
<script>
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
width: 1024,
height: 768,
transition: 'slide', // none/fade/slide/convex/concave/zoom
transitionSpeed: 'fast',
// Optional reveal.js plugins
dependencies: [
{ src: '/reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: '/highlight.min.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: '/reveal.js/plugin/zoom-js/zoom.js', async: true },
{ src: '/reveal.js/plugin/notes/notes.js', async: true }
]
});
/* This draws the graph on the slide on a slidechanged event */
Reveal.addEventListener('slidechanged', function(event) {
var callback = "render_"+event.currentSlide.id;
if(typeof(window[callback])=="function") {
window[callback]();
}
} );
/* This draws the graph if we got here directly without coming from another slide */
Reveal.addEventListener('ready', function(event) {
var callback = "render_"+event.currentSlide.id;
if(typeof(window[callback])=="function") {
window[callback]();
}
} );
</script>
</body>
</html>

39
confoo16a.xml Normal file
View File

@@ -0,0 +1,39 @@
<presentation
template="simple"
navmode="html"
titlecolor="#000000"
navbarbackground="#bbbbbb"
navbartopiclinks="0"
logo1="images/php-med-trans.png"
titlesize="6em"
navbarheight="3.5em"
examplebackground="#ffffff"
outputbackground="#ffffff"
exampleclass="noshadow"
exampleoutputclass="noshadow"
>
<topic>PHP</topic>
<title>Deploying PHP 7</title>
<event>Confoo</event>
<location>Montreal</location>
<date>Feb.25, 2016</date>
<speaker>Rasmus Lerdorf</speaker>
<url>http://talks.php.net/confoo16a</url>
<twitter>@rasmus</twitter>
<slide>slides/intro/titlepage.xml</slide>
<slide>slides/intro/bc7.xml</slide>
<slide>slides/intro/phan.xml</slide>
<slide>slides/intro/deploy_2016.xml</slide>
<slide>slides/intro/etsy_deploy.xml</slide>
<slide>slides/intro/php7prod.xml</slide>
<slide>slides/intro/numa.xml</slide>
<slide>slides/intro/driveshaft.xml</slide>
<slide>slides/intro/thank_you.xml</slide>
</presentation>

View File

@@ -1,6 +1,6 @@
<slide title="" section="bc7">
<blurb fontsize="20em" align="center">Top-3 Things that might bite you</blurb>
<blurb fontsize="20em" align="center">Top-5 Things that might bite you</blurb>
<break lines="3"/>
<blurb fontsize="1.5em" align="center">For the full list see</blurb>
<link fontsize="1.25em" align="center" margintop="-0.75em" href="http://php.net/manual/en/migration70.php">php.net/migration70</link>
@@ -40,6 +40,23 @@ echo preg_replace_callback(
<blurb fontsize="0.8em" align="left">Detection: grep, warnings in logs or unit test failures</blurb>
<break lines="1" section="bc7_3"/>
<blurb fontsize="1.1em" align="left">$HTTP_RAW_POST_DATA global removed</blurb>
<example fontsize="1em" result='0' title="" type="php"><![CDATA[
if (empty($GLOBALS['HTTP_RAW_POST_DATA']) &&
strpos($_SERVER['CONTENT_TYPE'], 'www-form-urlencoded') === false) {
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents("php://input");
}
]]></example>
<blurb fontsize="0.8em" align="left">Detection: grep, warnings in logs or unit test failures</blurb>
<break lines="1" section="bc7_4"/>
<blurb fontsize="1.1em" align="left">session.lazy_write enabled by default</blurb>
<example fontsize="1.1em" result='0' title="" type="ini"><![CDATA[
session.lazy_write = 0
]]></example>
<blurb fontsize="0.8em" align="left">Detection: Can cause out-of-band session read timing issues</blurb>
<break lines="1" section="bc7_5"/>
<blurb fontsize="1.1em" align="left">Invalid octal literals now produce a parse error</blurb>
<example fontsize="1.1em" result='0' title="" type="php"><![CDATA[
echo 05678; // PHP 5.x outputs 375

BIN
slides/intro/cpu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -5,14 +5,14 @@
<break lines="1" section="etsy_deploy0"/>
<blurb fontsize="2em" align="left">At Etsy we use irc</blurb>
<example fontsize="1.1em" result='0' title="" type="shell nohighlight"><![CDATA[
Channel: #push Topic: <prod> *joe *steve frank|bob
<example fontsize="0.9em" result='0' title="" type="shell nohighlight"><![CDATA[
Channel: #push Topic: <prod> *joe frank|bob
devbot: Swapping symlinks. Your code is about to start taking production traffic
pushbot: joe steve frank : Your code is live. Time to watch graphs: http://et.sy/abcd
pushbot: joe frank : Your code is live. Time to watch graphs: http://etsy/abcd
Rasmus: .join
*** pushbot has changed the topic on #push to <prod> joe steve frank|bob Rasmus
*** pushbot has changed the topic on #push to <prod> joe frank|bob Rasmus
frank: .good
*** pushbot has changed the topic on #push to <prod> *joe *steve *frank|bob Rasmus
*** pushbot has changed the topic on #push to <prod> *joe *frank|bob Rasmus
joe: .done
*** pushbot has changed the topic on #push to <prod> bob Rasmus
pushbot: bob Rasmus: You're up
@@ -38,21 +38,21 @@ Rasmus: .in
<image filename="deployinator.png"/>
<break lines="1" section="etsy_deploy3"/>
<example fontsize="1.1em" result='0' title="" type="shell nohighlight"><![CDATA[
<example fontsize="0.9em" result='0' title="" type="shell nohighlight"><![CDATA[
Channel: #push Topic: <princess> bob Rasmus
Jenkins: Starting build #36803 for job qa
Jenkins: Starting build #38784 for job princess
Jenkins: Project qa build #36803: SUCCESS in 6 min 19 sec: http://ci.etsy/job/qa/36803/
Jenkins: Project qa build #36803: SUCCESS in 6 min 19 sec: http://ci/job/qa/36803/
pushbot: bob Rasmus : qa tests have passed
devbot: [who_tried] Everyone in this push has run Try recently. w00t!
Jenkins: Project princess build #38784: SUCCESS in 1 min 10 sec: http://ci.etsy/job/princess/38784/
Jenkins: Project princess build #38784: SUCCESS in 1 min 10 sec: http://ci/job/princess/38784/
pushbot: bob Rasmus : princess tests have passed
bob: .good
Rasmus: .good
*** pushbot has changed the topic on #push to <princess> *bob *Rasmus
pushbot: bob Rasmus : everyone is ready, checking on Jenkins...
Jenkins: qa: last build: 36803 (9 min 5 sec ago): SUCCESS: http://ci.etsy/job/qa/36803/
Jenkins: princess: last build: 38784 (2 min 54 sec ago): SUCCESS: http://ci.etsy/job/princess/38784/
Jenkins: qa: last build: 36803 (9 min 5 sec ago): SUCCESS: http://ci/job/qa/36803/
Jenkins: princess: last build: 38784 (2 min 54 sec ago): SUCCESS: http://ci/job/princess/38784/
]]></example>
<break lines="1" section="etsy_deploy4"/>
@@ -64,18 +64,18 @@ Jenkins: princess: last build: 38784 (2 min 54 sec ago): SUCCESS: http://ci.etsy
</list>
<break lines="1" section="etsy_deploy5"/>
<example fontsize="1.1em" result='0' title="" type="shell nohighlight"><![CDATA[
<example fontsize="0.9em" result='0' title="" type="shell nohighlight"><![CDATA[
Channel: #push Topic: <prod> bob Rasmus
devbot: Swapping symlinks. Your code is about to start taking production traffic
pushbot: bob Rasmus : Your code is live. Time to watch graphs: http://etsy/et5cp
Jenkins: Starting build #39452 for job prod
pushbot: bob Rasmus : prod tests have passed
Jenkins: Project prod build #39452: SUCCESS in 30 sec: http://ci.etsy/job/prod/39452/
Jenkins: Project prod build #39452: SUCCESS in 30 sec: http://ci/job/prod/39452/
bob: .good
Rasmus: .good
*** pushbot has changed the topic on #push to <prod> *bob *Rasmus
pushbot: bob Rasmus : everyone is ready, checking on Jenkins...
Jenkins: prod: last build: 39452 (1 min 39 sec ago): SUCCESS: http://ci.etsy/job/prod/39452/
Jenkins: prod: last build: 39452 (1 min 39 sec ago): SUCCESS: http://ci/job/prod/39452/
bob: .done
pushbot: clear
*** pushbot has changed the topic on #push to clear

BIN
slides/intro/htop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
slides/intro/htop_ht.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
slides/intro/mem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

111
slides/intro/numa.xml Normal file
View File

@@ -0,0 +1,111 @@
<slide title="Hyperthreading and NUMA" section="numa">
<list>
<bullet fontsize="1em" type="circle">HyperThreading handles extreme loads better</bullet>
<bullet fontsize="1em" type="circle">If you don't have multi-socket servers, turn on HT and move on</bullet>
<bullet fontsize="1em" type="circle">For multi-socket servers, things get interesting</bullet>
</list>
<break lines="1" section="numa_singlesocket"/>
<example fontsize="1em" result='0' title="Digital Ocean" type="shell nohighlight"><![CDATA[
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz
Stepping: 2
CPU MHz: 1797.917
BogoMIPS: 3595.83
Virtualization: VT-x
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0,1
]]></example>
<break lines="1" section="numa_multisocket"/>
<example fontsize="1em" result='0' title="Multi-socket bare metal without HT" type="shell nohighlight"><![CDATA[
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 24
On-line CPU(s) list: 0-23
Thread(s) per core: 1
Core(s) per socket: 12
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Stepping: 2
CPU MHz: 1203.320
BogoMIPS: 5005.24
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0-11
NUMA node1 CPU(s): 12-23
]]></example>
<break lines="1" section="numa_multisocket_ht"/>
<example fontsize="1em" result='0' title="Multi-socket bare metal with HT" type="shell nohighlight"><![CDATA[
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 48
On-line CPU(s) list: 0-47
Thread(s) per core: 2
Core(s) per socket: 12
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
Stepping: 2
CPU MHz: 1200.000
BogoMIPS: 5004.73
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 30720K
NUMA node0 CPU(s): 0-11,24-35
NUMA node1 CPU(s): 12-23,36-47
]]></example>
<break lines="1" section="htop_graphs"/>
<image width="800" height="325" filename="htop_ht.png" align="center"/>
<image width="979" height="229" filename="htop.png" align="center"/>
<break lines="1" section="numa_graph"/>
<image width="979" height="507" filename="numa_ht.png" align="center"/>
<break lines="1" section="numa_solutions"/>
<break lines="1" />
<blurb fontsize="4em">Solutions?</blurb>
<list>
<bullet fontsize="1em" type="circle">numactl --interleave=all httpd/php-fpm</bullet>
<bullet fontsize="1em" type="circle">split multi-socket with containers</bullet>
<bullet fontsize="1em" type="circle">ignore it</bullet>
</list>
</slide>

BIN
slides/intro/numa_ht.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
slides/intro/perc95.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,8 @@
<slide title="PHP 7 in production" section="prod_perc95">
<image width="882" height="465" filename="perc95.png" align="center"/>
<break lines="1" section="prod_cpu"/>
<image width="882" height="465" filename="cpu.png" align="center"/>
<break lines="1" section="prod_mem"/>
<image width="882" height="465" filename="mem.png" align="center"/>
</slide>