Professional Documents
Culture Documents
Wim Godden
Cu.be Solutions
@wimgtr
Who am I ?
Wim Godden (@wimgtr)
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (https://cu.be)
Founder of Techpath Training Services (https://techpath.eu)
Open Source developer since 1997
Developer of PHPCompatibility, OpenX, ...
Speaker at PHP and Open Source conferences
Who are you ?
Developers ?
System engineers ?
Network engineers ?
DNS
Routing table
UDP
TCP BGP
IP SYN
Default gateway
MAC address
Basics : OSI model
Application
yer7 HTTP, DNS, SMTP, ...
La
Presentation
yer6 Serialization, data translation
La
Session
yer5 TLS, L2TP, SOCKS, PPTP, ...
La
Transport
yer4 TCP, UDP, ports, ...
La
Network
yer3 IP adressing
La
Data Link
yer2 Data protocol (ethernet, ...)
La
Physical
yer1 Wires, network card, wireless interface
La
Basics : packets
Physical cable
01011010111010 01011010111010
or wireless
Basics : packets
Packets always consist of :
Header
Contents
Packets contain other packets :
Packet type #1 header
Packet type #1 contents
Packet type #2 header
Packet type #2 contents
Packet type #3 header
etc.
Destination MAC (6 bytes) Source MAC (6 bytes) Type (2 bytes)
Payload (46 – 1500 bytes) CRC (4 bytes)
Problem :
Multiple devices sending at same time
→ network collision
→ packet retransmit at TTL
Sending on a local network Layer 2
Each network device (port) has a MAC address
Assigned by manufacturer
Can be overwritten (for VM or failover)
Same physical network → send packet to MAC address
Switch knows MAC address(es) of devices and forwards traffic
Sending IP traffic on local network Layer 3
Requires IP addresses
Where to send ? We need to know MAC address
Uses ARP (Address Resolution Protocol) for lookup
16:58:56.933019 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.0.15 tell 192.168.0.12, length 28
16:58:56.938019 ARP, Ethernet (len 6), IPv4 (len 4), Reply 192.168.0.15 is-at 00:50:56:8b:6a:b7, length 46
In reality :
8 bits 8 bits 8 bits 8 bits
11000000 00000100 00100000 00000001
192 . 4 . 32 . 1
IP networking requires :
IP address
Subnet mask
Subnet mask
Defines the range to which the IP belongs
IPs within the same range can talk to each other directly (local)
MAC for
192.168.0.2 ?
AA:BB:CC:DD:EE:FF
Client Server
192.168.0.15/24 192.168.0.2/24
Let’s talk !
How do IP packets find their way ? → Routing !
Each (Layer 3) network node has a routing table
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 204 0 0 eth1
10.0.0.0 0.0.0.0 255.255.0.0 U 204 0 0 eth1
10.0.64.0 192.168.201.101 255.255.192.0 UG 0 0 0 eth0
192.168.201.0 0.0.0.0 255.255.255.0 U 202 0 0 eth0
AA:BB:CC:DD:EE:FF
Client Server
SYN Sequen
ce no =
1000
SYN ACK
1
nc e no = 100 00
Seque dge no = 90
le
ACK Acknow
Sequenc
Acknowle e no = 1002
Data dge no =
9001
Establishing a TCP connection
Client Server
SYN 0 Sequen
ce no =
1000
45 SYN ACK
1
nc e no = 100 00
Seque dge no = 90
le
ACK 90 Acknow
Sequenc
Acknowle e no = 1002
Data dge no =
9001
135
Establishing a TCP connection
10ms London
Brussels 45ms Montreal
Client Server
SYN 0 Sequen
ce no =
1000
10
45 SYN ACK
1
nc e no = 100 00
Seque dge no = 90
20 le
ACK 90 Acknow
Sequenc
Acknowle e no = 1002
Data dge no = 30
9001
135
TCP Window Size
Brussels Montreal
Client Server
SYN
SYN ACK
92
rwnd = 81
ACK rwnd = 8192
DATA
384
rwnd = 16
sysctl net.ipv4.tcp_window_scaling
TCP Slow Start
Client Server
0
45
90
135
180
225
TCP Slow Start
Client Server
0
45
90
135
180
225
New vs existing connection
Brussels 45ms Montreal
Client Server
SYN 0
45 SYN ACK
ACK 90
GET /url
135
Processing request
235 DATA
(x4)
ACK
(x4) 280
DATA
325
(x8)
ACK
(x8) 370
415
New vs existing connection
Brussels 45ms Montreal
Client Server
DATA 0
GET /url
45
Processing request
DATA
145 (x12)
ACK
(x12) 180
225
TCP Performance
Upgrade to latest Linux kernel or OS
Check window size
Reduce latency (move servers closer to client)
Reuse already established connections
SSL/TLS
Client Server
SYN 0
45 SYN ACK
ACK 90
ServerHello
ClientHello 135 Certificate
ServerHelloDone
ClientKeyExchange
ChangeCipherSpec 180
Finished ChangecipherSpec
225 Finished
DATA 270
315
SSL/TLS with Session Resumption
Client Server
SYN 0
45 SYN ACK
ACK 90
ServerHello
ClientHello 135 ChangecipherSpec
Finished
ChangeCipherSpec
Finished
180
225
DATA
270
315
TLS → HSTS
HSTS = HTTP Strict Transport Security
Remembers that a site is HTTPS-only
Prevents users from going to http:// then redirected to https://
Prevents leaking of session cookies over unsecured wifi
UDP
User Datagram Protocol
Unreliable Datagram Protocol
Connectionless
→ No 3-way handshake required
Simple packet structure
Bit 0-3 4-7 8-11 12-15 16-19 20-23 24-27 28-31
0 Source port Destination port
32 Length Checksum
< Contents of the packet >
UDP
Bit 0-3 4-7 8-11 12-15 16-19 20-23 24-27 28-31
0 Source port Destination port
32 Length Checksum
< Contents of the packet >
Source and Destination ports
Destination port : defined by service
HTTP : TCP port 80
HTTPS : TCP port 443
DNS : UDP port 53
Source port : for identification of a connection
5000 80
5001 80
5002 80
Client Server
cu.be DNS
server
DNS lookups
Actual lookups depend on type of DNS record
DNS holds lots of things :
A record = pointer to IPv4 addresses
AAAA record = pointer IPv6 addresses
CNAME records = aliases for A records
MX records = mail servers
NS records = DNS servers
TXT = various stuff (anti-spam mostly)
Router
Router AS 10
AS 5
News ticker :
XML feed from other site (owned by same customer)
Cached for 15 min
Customer X – fetching the feed
unlink(APP_DIR . '/tmp/cacheFile.xml');
file_put_contents(
APP_DIR . '/tmp/cacheFile.xml',
file_get_contents('http://www.scrambledsitename.be/xml/feed.xml')
);
Feed source
Customer X – no feed without the source
Feed source
Customer X : timeout
default_socket_timeout : 60 sec by default
Each visitor : 60 sec wait time
People keep hitting refresh → more load
More active connections → more load
Apache hits maximum connections → entire site down
Customer X – fetching the feed
$context = stream_context_create(
array(
'http' => array(
'timeout' => 5
)
)
);
if (filectime(APP_DIR . '/tmp/cacheFile.xml') < time() - 900) {
$feed = file_get_contents(
'http://www.scrambledsitename.be/xml/feed.xml',
false,
$context
);
if ($feed !== false) {
file_put_contents(
APP_DIR . '/tmp/cacheFile.xml',
$feed
);
}
Customer X : process early
$context = stream_context_create(
array(
'http' => array(
'timeout' => 5
)
)
);
if (filectime(APP_DIR . '/tmp/cacheFile.xml') < time() - 900) {
$feed = file_get_contents(
'http://www.scrambledsitename.be/xml/feed.xml',
false,
$context
);
if ($feed !== false) {
file_put_contents(
APP_DIR . '/tmp/cacheFile.xml',
ParseXmlFeed($feed)
);
}
Customer X : file_[get|put]_contents atomicity
None of these are perfect, but all of them are better than waiting 60 seconds and then
showing an unhandled error !
Sendig HTTP requests : rights and wrongs
Right :
Use a library
Examples : guzzle/guzzle, rmccue/requests, krisswallsmith/buzz (also available for React),
nategood/httpful
Sort-of-ok :
Using curl
Wrong :
file_get_contents (or similar) on a URL
fsockopen to port 80, then sending ‘GET / HTTP/1.0’, …
Connecting to services
Always handle failures on connection
$link = mysql_connect() or die(mysql_error());
Connecting to services
Always handle failures on connection
Fallback to cache
Fallback to secondary service
At least show a nice error message
Did I mention logging and alerting ?
Another example :
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
Connecting to services
Always handle failures on connection
Fallback to cache
Fallback to secondary service
At least show a nice error message
Did I mention logging and alerting ?
Another example :
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
try {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
} catch (AMQPTimeoutException $e) {
// Do something nice for the user… they’re your user after all
}
$channel = $connection->channel();
Async for multiple or slow requests
Need multiple pieces of data → handle them asynchronously
PHP has amazing asynchronous libraries
Pthreads
ReactPHP
Icicle
Amp
...
Slow requests → asynchronous again or queue them
RabbitMQ
Zeromq
...
Tools to simulate bad networks - Wanem
Tools to simulate bad networks - Linux
IPTables
iptables -A INPUT -m statistic --mode random --probability 0.1 -j DROP
iptables -A OUTPUT -m statistic --mode random --probability 0.1 -j DROP
TC (Traffic Control)
tc qdisc add dev eth0 root netem delay 50ms 20ms distribution normal
tc qdisc change dev eth0 root netem reorder 0.02 duplicate 0.05 corrupt
0.01
Comcast (https://github.com/tylertreat/comcast)
“Simulating shitty network connections so you can build better systems”
Uses IPTables + TC in an intelligent way
If your data room looks like...
It can be done
Failover, disaster recover are great...
… if they work !
Thanks !