Building Scalable PHP Applications Using Google's App Engine

30 downloads 211 Views 6MB Size Report
Building Scalable PHP Applications. Using Google's App Engine. Mandy Waite google.com/+MandyWaite. @tekgrrl. Amy Unruh g
Building Scalable PHP Applications Using Google’s App Engine Mandy Waite google.com/+MandyWaite @tekgrrl

Amy Unruh google.com/+AmyUnruh @amygdala

Why Cloud for PHP?

Scale on Demand

Fast Access to Cloud-Scale Services

Analytics

Focus on developing your App

Global Availability

App Engine

Simple to Scale - AutoScale

Easy to develop - Free to start - Local dev environment - Service abstractions

Trivial to manage - Fully managed - No patches - 24x7 operation by Google SREs

Handling variable load Volatile Demand Fluctuation

Steady Demand Growth

Inefficiency

Downtime

Inefficiency

With App Engine only pay for what you use

With App Engine scale with efficiency and reliability

App Engine’s Cloud Scale Services Cloud Datastore PageSpeed

Cloud SQL

Cloud Storage

Memcache

Cron Jobs

...and more

Why PHP? Top feature request for App Engine

Real World Example Converting joind.in to App Engine

PHP on App Engine: what’s the environment like?

github.com/GoogleCloudPlatform/appengine-php - 5.4.19 http://php-minishell.appspot.com/phpinfo: Production phpinfo()

How do we start? appengine.google.com

app.yaml

application: version: uno runtime: php api_version: 1 handlers: - url: /inc static_dir: inc - url: /.* script: index.php

What is the environment like?

php.ini

google_app_engine.enable_functions = "php_sapi_name"

How do we log?

How do we log? function write_log($level = 'error', $msg, $php_error = FALSE) { if ($this->_enabled === FALSE) { return FALSE; } $level = strtoupper($level); if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) { return FALSE; } syslog($level == 'ERROR' ? LOG_ERR : LOG_INFO, $msg); return TRUE; }

How do we log?

Hmmm… now we have a database error

What about the database?

What about the database?

$db['default']['hostname'] = ":/cloudsql/:"; $db['default']['username'] = "joindin"; $db['default']['password'] = "password"; $db['default']['database'] = "joindin"; $db['default']['dbdriver'] = "mysql"; $db['default']['dbprefix'] = ""; $db['default']['pconnect'] = TRUE;

How do we call APIs?

Recommended: use App Engine’s URLFetch service via standard HTTP stream wrappers and functions like file_get_contents()

Calling APIs? $opts = array( 'http' => array( 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-length: ".strlen($msg)."\r\n", 'content' => $msg)); $ctx = stream_context_create($opts); $resp = file_get_contents( 'http://api.defensio.com' . $loc, false, $ctx);

How do we cache?

Output Caching function _write_cache($output) { $CI =& get_instance(); $path = $CI->config->item('cache_path'); $cache_path = ($path == '') ? BASEPATH . 'cache/' : $path; $uri = $CI->config->item('base_url') . $CI->config->item('index_page') . $CI->uri->uri_string(); $cache_path .= md5($uri); $mc = new Memcache; $mc->set($cache_path, $output, $this->cache_expiration * 60); return; }

Can we upload files?

Uploads?

cloud.google.com/console

App Engine Access to Cloud Storage

Uploads?

$options = [ 'gs_bucket_name' => 'joindin' ]; $upload_url = CloudStorageTools::createUploadUrl( '/event/edit/'.$this->edit_id, $options); echo form_open_multipart($upload_url);

Uploads?— and Cloud Storage stream wrapper $gs_name = $_FILES[$field]['tmp_name']; $gs_type = $_FILES[$field]['type']; $options = [ "gs" => [ "Content-Type" => $gs_type, "acl" => 'public-read']]; $ctx = stream_context_create($options); rename($gs_name, $this->upload_path . $this->file_name, $ctx);

Public URLs from Cloud Storage Files?