Upload
fwdays
View
640
Download
4
Embed Size (px)
Citation preview
Upwork PHP Architecture
Sep NasiriSoftware Architect at Upwork
Introduction
● Legacy Stack● Challenges and reasons for modernization● Overview of Upwork Architecture ● Focus on Presentation Tier and PHP
Legacy Stack
● Presentation Layer○ PHP / Zend Framework ○ jQuery / Custom CSS
● Perl RPC Layer● Both layers deployed to a cluster of App
Servers● Deployed in hardware in our data center
Problems with Legacy Stack
● Infrequently releases○ Weekly, then 3x a week ○ Release blockers - problems in one part
of the application would block other teams features
● Aging codebase ○ frameworks getting out dated but hard
to upgrade
Requirement for New Architecture
● Isolate risk○ problems in one part of the application
should not affect other parts● Teams work in independent swimlanes
○ develop, test, and deploy independently○ deploy features when ready
● Allow advanced deployment techniques○ Automated○ Blue/Green ○ Canary
New Backend Architecture - Agora
● Replace Perl Layer ● Java● Microservices● Netflix Open Source Software
○ Hystrix ○ Eureka
● AWS
Extending Microservices to the Frontend - Agate ● Wanted to extend the benefits of Agora to
the presentation tier. ● Spit up our PHP and client side code (JS,
CSS, HTML) into independent units● Challenges
○ Dealing with routing○ Navigation / Header ○ Logging / Visibility
Agate Stack
● PHP / Symfony 2● Angular JS● Bootstrap
Agate Stack
● PHP / Symfony2○ Lots of custom bundles
■ Distributed using Composer / Satis ● Component Library
○ Bootstrap ○ Angular
● Navigation Service
Talking to Agora - Phystrix
● Based on Netflix Hystrix● Command Pattern● Circuit breaker
○ prevent cascading failures ● Fallbacks
Open Source - https://github.com/odesk/phystrix
Phystrix Exampleuse Odesk\Phystrix\AbstractCommand;
/**
* All commands must extends Phystrix's AbstractCommand
*/
class MyCommand extends AbstractCommand
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
/**
* This function is called internally by Phystrix, only if the request is allowed
*
* @return mixed
*/
protected function run()
{
return 'Hello ' . $this->name;
}
}
Phystrix Example$myCommand = $phystrix->getCommand('MyCommand', 'Alex'); // 'Alex' is passed to MyCommand's constructor
$result = $myCommand->execute();
Visibility
● Metrics ○ graphite○ metrics bundle
■ times actions■ allows developers to add custom
timers● Logstash / Elasticsearch / Kibana
○ aggregate logs
Testing
● PHPUnit● Mocha
○ small test - karma○ medium tests - protractor
● Jenkins ○ Docker build of each project○ run tests in Docker
Planned improvements
● Docker based deployments○ unify Agate and Agora deployment
● Continuous Integration / Delivery ○ improve our testing pipeline and Allow
fully automated deployments ● Configuration with Consul to allow Docker
images to move from dev to stage to prod
Thank You