Serving Raster Layers On Google Cloud Platform
Serving Raster Layers On Google Cloud Platform
Lastupdated:22December2014
Contents
Introduction
1.ConfigureaCloudPlatformprojectforservingrasters
2.UploadtilestoGoogleCloudStorage
Accesscontroldecisions
Maptiles
Uploadingtilesinbulkforpublicaccess
Uploadingtilesinbulkforprivateaccess
3.UsetilesfromGoogleCloudStoragewiththeGoogleMapsAPI
MapsAPIPublictilesexample
MapsAPIGoogleCloudStoragecookieauthexample
MapsAPIGoogleCloudStorageOAuth2.0Example
Howthisdemoworks
4.WrapOGCendpointsaroundtilesfromGoogleCloudStoragewithGoogleCompute
Engine
CreatingaGoogleComputeEngineVM
InstallingandconfiguringMapProxy
Loadbalancing
CreateasnapshotofyourworkingMapProxyVM
Createadiskfromthesnapshot
Createanimagefromthedisk
Createaninstancetemplate
CreateanInstanceGroup
CreateanHTTPloadbalancer
Thirdpartyproducts:ThisdocumentdescribeshowGoogleproductsworkwiththird
partyproductsand
theconfigurationsthatGooglerecommends.Googledoesnotprovidetechnicalsupportforconfiguring
third
partyproducts.GOOGLEACCEPTSNORESPONSIBILITYFORTHIRD
PARTYPRODUCTS.Please
consulttheproduct'swebsiteforthelatestconfigurationandsupportinformation.Youcanalsocontact
GooglePartnersforconsultingservices.
GoogleMapsforWork1/35
Introduction
ThisdocumentshowsyouhowtoservecustomrasterlayersusingGoogleCloudStorage,
GoogleComputeEngine,andtheGoogleMapsAPI.Thisapproachisusefulifyouhavea
largequantityofsatelliteoraerialimagerythatyouneedtoserveatscaleontoaGooglemap
orotherGIStool.
Usingthisdocument,youllcompletethefollowingsteps:
1. ConfigureaGoogleCloudPlatformproject.
2. UploadimagerytilestoGoogleCloudStorage.
3. DisplaytilesusingtheGoogleMapsAPI.
4. ServemaptilesusingOGCstandards.
5. Loadbalanceyourapplication.
Note:Thisdocumentdoesnotdescribehowtocreaterastertilesandassumesyoualready
haverastertilestouploadandhostinGoogleCloudStorage.Youcanuseoneofmany
thirdpartytoolstocreaterastertiles.
Beforeyoubegin,makesureyouhaveaGoogleAccount.ConsiderusingasharedGoogle
Accountforyourorganization,ratherthanapersonalGoogleAccount.
1. SignintotheGoogleDevelopersConsoleandclickCreateProject.
GoogleMapsforWork2/35
2. Enablebilling.
FordetailsaboutbillinginGoogleCloudPlatform,seetheGoogleAPIsConsoleHelp.
3. Addacreditcardorbankaccounttotheprojectforhosting(storage)anddownloading
(egress)thesourceimageryforthecontractterm.
GoogleCloudPlatformprovidesacalculatorforestimatingmonthlybillingcharges
basedonusage.
4. CreateaGoogleCloudstoragebucket.
Note:Cloudstoragebucketsareglobal,soifthenameyouchooseisalreadyinuse,
chooseadifferentname.
5. InstallandauthenticatetheGoogleCloudSDKtoeasilyconductbulkdownloads.
Followtheinstallationinstructionsforyouroperatingsystem.
OnceyouinstalltheSDK,youllhavenewsystemcommandslikegcloudand
gsutil.
GoogleMapsforWork3/35
6. UsethefollowingcommandtoauthorizetheCloudSDKtoyourGoogleAccount.Use
thesameGoogleAccountyouusedfortheowneroftheCloudPlatformProjectand
theImageryBucket.
$gcloudauthloginprojectyourprojectname
Detailsaboutthiscommand
AnOAuth2authorizationscreenwillopenabrowserwindow,givingtheCloudSDK
accesstoyourproject.
GoogleMapsforWork4/35
Withpublicaccess,thetilesyouplaceonGoogleCloudStorageareaccessibletoanyoneon
theInternet.Withprivateaccess,onlythosetowhomyouexplicitlygrantaccesscanviewthe
tiles.
PrivateaccessiscontrolledusingOAuth2.0,andrequiresviewerstopresentcredentials
basedoneofthefollowing:
AGoogleAccount(suchasGmailorGoogleApps)
AGoogleAccountthatisamemberofanapprovedGoogleGroup
Accessviaathirdpartyserviceorproxythathandlesauthenticationviaserverside
authentication(awebservicethatacceptsausernameandpasswordandproxiesdata
withaserversideaccesstoken).
Map tiles
Maptilescanhavevariousnamingstandardsandcanvarybasedonmapprojection.This
documentfocusesonmaptilesinaz/x/y.pngnamingstandard,where
Zisthecurrentzoomlevel,and
XistheXcoordinateandYistheYcoordinate,measuredfromthetopleftofthemap
foreachzoomlevel
GoogleMaps,ESRI,Bing,OpenStreetMap,andothersusethistopleftstandard.However,
theOGCstandard,calledTMS,startsfromthebottomleft.
Youcanseethedifferencesinthetwoexamplesbelow,whichshowatypicaltilesfile
structure(Z/X/Y.png),where,inthe4thXcolumnofzoomlevel4,therearetwoimagesfor
theYcoordinates.Notethattheirnamesaredifferentbasedonwhethercountingbeganat
thetopleftofbottomleft.
GoogleMapsforWork5/35
Thefilestructureinwhichyoursoftwareexportedthetileswilldeterminethelogicyouneedto
useinyourapplicationwhenyouwanttoloadaspecifictile.However,thefilestructure
doesntimpacttheactualuploadprocess.
Forexamplepurposes,thisdocumentusestheUSGSNationalLandCoverDatabase.
TomakethetilespubliclyaccessibletoanyoneontheInternet,setthedefaultACLforthem
aspublicread.Inthedirectorywhereyouhaveyourtilesinasubfoldercalledzxy,run:
$gsutilmcpapublicreadRzxy/gs://usgslandcoverdemo/
Detailsaboutthiscommand
Themparameterwillmakethecpprocessruninparallelthreads,whichwillgreatlyspeed
upyourupload.
Tomanageaccesstoprivatetiles,youcanuseGoogleGroups.WithGroups,itseasyto
grantreadpermissiontoaGoogleCloudStoragebuckettomembersofagroup,andthen
managewriteaccessforindividualusersusingthestandardGoogleGroupsadministration
tools.Forthisexample,welluseagroupnamedCloudStorageTilesPrivate.Tojointhis
group,clickJoinonthispage:
GoogleMapsforWork6/35
https://groups.google.com/forum/#!forum/cloudstoragetilesprivate
$gsutilmbpcloudstoragetilesdemogs://usgslandcoverdemoprivate/
[email protected]:R
gs://usgslandcoverdemoprivate/
3. Use tiles from Google Cloud Storage with the Google Maps API
Maps API Public tiles example
Seethedemo
ThefollowingcodesnippetshowstheGoogleMapsAPIJavaScriptyouneedtocallthetiles
asaGoogleMapsAPIImageMapType.Thesefilesresideinthe/z/x/y.pngstructureinthe
samebucketinwhichtheHTMLthatloadstheMapsAPIresides.
GoogleMapsforWork7/35
varimageMapType=newgoogle.maps.ImageMapType({
getTileUrl:function(coord,zoom){
varproj=map.getProjection()
varz2=Math.pow(2,zoom)
vartileXSize=256/z2
vartileYSize=256/z2
vartileBounds=newgoogle.maps.LatLngBounds(
proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,
(coord.y+1)*tileYSize)),
proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*
tileXSize,coord.y*tileYSize))
)
return
"{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)
},
tileSize:newgoogle.maps.Size(256,256),
minZoom:mapMinZoom,
maxZoom:mapMaxZoom,
name:'Tiles'
})
YoucanalsohosttheHTMLpageonGoogleAppEngine,GoogleComputeEngine,oryour
ownwebserverandstillpointtotilesinaGoogleCloudstoragebucket.Todothis,just
modifytheURLfromalocalreferencetoaremotereference,asfollows:
return
"{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace(
'{y}',coord.y)to
return
"http://storage.googleapis.com/usgslandcoverdemo/zxy/{z}/{x}/{y}.pn
g".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)
ForTMStiles,youneedtofliptheYcoordinate,asshowninthefollowingcodesample:
varimageMapType=newgoogle.maps.ImageMapType({
getTileUrl:function(coord,zoom){
varproj=map.getProjection()
varz2=Math.pow(2,zoom)
vartileXSize=256/z2
vartileYSize=256/z2
vartileBounds=newgoogle.maps.LatLngBounds(
proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,
(coord.y+1)*tileYSize)),
proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*
tileXSize,coord.y*tileYSize))
)
//FliptheYvalue
varymax=1<<zoom
varY=ymaxcoord.y1
return
"{z}/{x}/{y}.png".replace('{z}',zoom).replace('{x}',coord.x).replace('{y}',Y)
GoogleMapsforWork8/35
},
tileSize:newgoogle.maps.Size(256,256),
minZoom:mapMinZoom,
maxZoom:mapMaxZoom,
name:'Tiles'
})
Seeademo
Forthisexample,wellusetheGooglegroupnamedCloudStorageTilesPrivate.Tojointhis
group,clickJoinonthispage:
https://groups.google.com/forum/#!forum/cloudstoragetilesprivate
Youmustbeamemberofthisgrouptoviewthetilesinthefollowingdemo:
https://storage.cloud.google.com/usgslandcoverdemo/zxy/cookiezxy.html
FromtheGoogleCloudStorageDocumentation:
GoogleCloudStorageletsyouprovidebrowserbasedauthenticateddownloadsto
userswhodonothaveGoogleCloudStorageaccounts.Todothis,applyGoogle
AccountbasedACLstotheobjectandthenprovideuserswithaURLthatisscopedto
theobject.TheURLforbrowserbasedauthenticateddownloadsis:
https://storage.cloud.google.com/bucket/object
Note:ThisURLbaseisslightlydifferentthanthe
http://storage.googleapis.com/basethisdocumentusesforthepublicmap
examples.
OnceyouveuploadedyourHTMLfile,youcanaddormodifythepermissions.Makesure
youveappliedthegroupyoureusingforthebucketsdefaultreaderACL.
GoogleMapsforWork9/35
WhenauservisitstheprivatewebpageURLintheirbrowser,theuserisautomatically
promptedtosignintotheirGoogleAccount(ifnotalreadysignedin).Aftertheuseris
authenticatedandthebrowserhasacquiredacookiewithanencapsulatedidentitytoken,the
userisredirectedtothepageintheGoogleCloudStoragerepository.GoogleCloudStorage
thenverifiesthattheuserisallowedtoreadthepage,andthenloadsthepageintothe
browser.
Inthecodesamplebelow,notethatitisarequirementthattheabsolute,andnotlocalized
URLpattern,begivenforthetiles:
varimageMapType=newgoogle.maps.ImageMapType({
getTileUrl:function(coord,zoom){
varproj=map.getProjection()
varz2=Math.pow(2,zoom)
vartileXSize=256/z2
vartileYSize=256/z2
vartileBounds=newgoogle.maps.LatLngBounds(
proj.fromPointToLatLng(newgoogle.maps.Point(coord.x*tileXSize,
(coord.y+1)*tileYSize)),
proj.fromPointToLatLng(newgoogle.maps.Point((coord.x+1)*
tileXSize,coord.y*tileYSize))
)
return
"https://storage.cloud.google.com/usgslandcoverdemo/zxy/{z}/{x}/{y}.png".replace('
{z}',zoom).replace('{x}',coord.x).replace('{y}',coord.y)
},
tileSize:newgoogle.maps.Size(256,256),
minZoom:mapMinZoom,
maxZoom:mapMaxZoom,
name:'Tiles'
})
Forthisexample,wellagainusetheGooglegroupnamedCloudStorageTilesPrivate.To
jointhisgroup,clickJoinonthispage:
https://groups.google.com/forum/#!forum/cloudstoragetilesprivate
Youmustbeamemberofthisgrouptoviewthetilesinthefollowingdemo:
GoogleMapsforWork10/35
http://storage.googleapis.com/usgslandcoverdemoprivate/zxy/privatezxy.html
Asamemberofthegroup,youllfirstseeapagethatasksyoutoauthorize.Clickthe
AuthorizebuttontoprovidetherequiredclientsideOAuth2.0credentialstoaccessthetiles.
Next,youllseeascreenthatasksyoutogranttheapplicationpermissiontoaccessfilesin
GoogleCloudStorageonyourbehalf.
ClickAccept.AmapwillappearandloadtheprivatelyACLdtiles.
GoogleMapsforWork11/35
//TheoauthscopefordisplayingGoogleCloudStoragedata.
varscopes='https://www.googleapis.com/auth/devstorage.read_only'
varaccess_token=''
functioninitialize(){
authorizationFlow(authorizationComplete,refreshComplete)
}
functionauthorizationComplete(authResult){
access_token=authResult.access_token
initMap()
}
ThiscodeconfigurestheOAuth2.0Workflowparameters.Thefirstdefinedvariableisan
OAuth2.0ClientID.
TocreateaClientID:
1. FromtheAPIs&AuthlistintheDevelopersConsoleproject,clickCredentials.
GoogleMapsforWork12/35
2. ClickCreatenewClientID:
3. OntheCreateClientIDscreen,selectWebapplication(default)fortheApplication
Type.(Thisapplicationisaccessedbyawebbrowseroveranetwork,andisnota
serversideorinstalledapplication.)
4. ClickConfigureconsentscreen.
GoogleMapsforWork13/35
Theuserseestheconsentscreenafterinvokingthefunctiontoauthorizethe
application.Werecommendthatyouprovidelogosandlinksforyourapplication,to
encourageuserstotrusttheapplicationtowhichtheyaregrantingpermissionsto
accesstheirdata.
5. Ataminimum,enteryourcontactemailaddressandaprojectname.ThenclickSave.
6. OntheCreateClientIDscreen,providetheAuthorizedJavaScriptOriginsandthe
AuthorizedRedirectURIs.
GoogleMapsforWork14/35
ThisinformationpreventssomeonefromcopyingyourHTML/JavaScriptandhostingit
onaninsecureorthirdpartyserver,tointerceptuserdataoruseyourprojectsquotas.
Inthisexample,wewanttohostaprivatemaponGoogleCloudStorage,soweneed
tosettheAuthorizedJavaScriptOriginstohttp://storage.gooogleapis.com.
WealsoneedtosettheAuthorizedRedirectURIstothefinalURLatwhichthe
HTMLpagewillbehosted.Oncetheuserisauthorized,theOAuthworfklowredirects
theuserbacktotheoriginalpage,thistimewithaURLparameterthatistheiraccess
token.Whentheapplicationseesthattheresanaccesstoken,itwillthenreplacethe
blankpagewiththeAuthorizebuttonbyinitializingtheGoogleMapsAPI.
Finally,auniqueClientIDentrywillbecreated.YoulladdthisClientIDtothe
JavaScriptforthevariableclientIDintheexample.
GoogleMapsforWork15/35
ThefollowinglinedefinestheOAuth2.0Scope,whichprovidesthedataaccessrightsthatthe
applicationneedstheusertogranttotheapplication:
varscopes='https://www.googleapis.com/auth/devstorage.read_only'
AtGoogle,thesescopesaretiedtoindividualservices.Inthiscase,wearecallingthe
devstoragescope(GoogleCloudStorage),andbecausetheuserjustneedstoaccess(not
write)tiles,theapplicationonlyneedsread_onlyaccess.Itsbesttokeepscopesasnarrow
andconservativeaspossible,bothforsecurityandusertrust.Forexample,youwouldntwant
tograntawebpagethatissupposedtoshowyourmaptilestheabilitytoposttoyour
Google+profileorreadyourGmailcontactslist.
Becausewewanttoallowuserstoaccessthewebpagebeforetheusersprovidetheir
credentialstoinitiatetheOAuth2.0workflow,weneedtomaketheactualwebpagepublically
accessible.Dontworry,userswillnotbeabletoaccesstheprivatelyACLdtilesinthe
bucket,becausewearenotgoingtomodifytheirACLshowever,wellmaketheHTMLpage
inthebucketpublicallyaccessible.
GoogleMapsforWork16/35
NotethatOAuth2.0credentialsexpireafteragivenamountoftime.AtGoogle,thedefault
timeoutis60minutes.Thetimeoutisasecurityfeaturethatpreventssomeonewhomayhave
nefariouslyinterceptedanaccesstokenfromusingthattokenforaprolongedperiodoftime.
Thisapplicationrefresheseveryhourtoretrieveafreshaccesstoken:
functionhandleAuthResult(authResult){
varauthorizeButton=document.getElementById('authorize_button')
//Hastheuserauthorizedthisapplication?
if(authResult&&!authResult.error){
//Theapplicationisauthorized.Hidethe'Authorization'button.
authorizeButton.style.display='none'
authorization_complete(authResult)
//Wemustrefreshthetokenafteritexpires.
window.setTimeout(refreshToken,authResult.expires_in*1000)
Finally,unlikethepublicexamples,theprivateexamplesappendaqueryparametertothetile
URL,?access_token={access_token}.Whenrequestingdatathatsprotectedbyprivate
ACLsfromGoogleCloudStorage,youmustpasstheaccess_tokenqueryparameterwitha
validandproperlyscopedaccesstoken.
return
"{z}/{x}/{y}.png?access_token={access_token}".replace('{z}',zoom).replace('{x}',coor
d.x).replace('{y}',coord.y).replace('{access_token}',access_token)
GoogleMapsforWork17/35
ToenableOGCcompliantendpoints,youcanhostaccesstotheimagerytilesfromthe
opensourceapplicationMapProxy.Inthissection,youllcreateaLinuxvirtualmachinewithin
GoogleComputeEnginetohostMapProxy,andalsocreateacustomfirewallconfigurationto
permitincomingtraffictoMapProxy.
TheGoogleComputeEngineDevelopersCenterhasseveralresourcestohelpyouget
startedrunningvirtualmachines,andindepthinformationforconfiguringfirewallrules.
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickNetworks.
2. UnderAllnetworks,clickdefaulttoaddanewfirewallrule.Thisruleletsyoutestthe
developmentserveronport8080.
3. Createafirewallrule.
GoogleMapsforWork18/35
4. Enableport80byclickingonAllowHTTPtraffic.
1. CreateanewUbuntu14.04ComputeEngineinstanceinyourproject:
gcloudcomputeinstancescreatemapproxyimage
ubuntu1404trustyv20141031aimageprojectubuntuoscloudzone
uscentral1a
2. ConnectviaSSH,usingaterminalortheDevelopersConsolebrowserterminal.
$sudoaptgetupdate
$sudoaptgetinstallpythonvirtualenv
$sudomkdir/mapproxy
$sudochmod777/mapproxy
$cd/mapproxy
$virtualenvsystemsitepackagesmapproxy
$sudoaptgetinstallpythonimagingpythonyamllibproj0
$sudoaptgetinstalllibgeosdevpythonlxmllibgdaldevpythonshapely
GoogleMapsforWork19/35
$sudoaptgetinstallbuildessentialpythondevlibjpegdevzlib1gdev
libfreetype6dev
$sourcemapproxy/bin/activate
$pipinstallMapProxy
$nanogcs.yaml
3. CopyandpastethefollowingMapProxyconfigurationfileintothenanoeditor.Note
thatyoullneedtochangetheURLparametertomatchyourGCSbucket.
services:
demo:
tms:
use_grid_names:true
#originfor/tilesservice
origin:'nw'
kml:
use_grid_names:true
wmts:
wms:
md:
title:MapProxyGoogleCloudStorage
abstract:ThisisaminimalMapProxyexample.
layers:
name:gcs
title:GoogleCloudStorage
sources:[gcs_cache]
caches:
gcs_cache:
grids:[webmercator]
sources:[gcs]
sources:
gcs:
type:tile
grid:webmercator
url:
http://storage.googleapis.com/usgslandcoverdemo/zxy/%(z)s/%(x)s/%(y)s
.png
coverage:
srs:'EPSG:4326'
bbox:[125.850,24.530,66.800,50.289]
grids:
webmercator:
base:GLOBAL_WEBMERCATOR
4. Savethefile(Ctrl+O)andexit(Ctrl+X)Youcannowtesttheconfiguration.
$mapproxyutilservedevelopb0.0.0.0:8080gcs.yaml
GoogleMapsforWork20/35
5. Visitthedevelopmentserverat:
http://YourIP:8080/demo/
Therewillbeseveraldifferentservices,basedontheconfigurationfilethatyou
used.
6. ClickanyofthePNGorJPEGlinkstotryouttheOGCservices.
GoogleMapsforWork21/35
7. Onceeverythingappearstobeworking,configureMapProxytoworkwith
ApacheviaWSGI.
$Ctrl+Ctokillthedevelopmentserver
$rmrfcache_data
$mapproxyutilcreatetwsgiappfgcs.yamlconfig.py
$deactivate
$sudoaptgetinstallapache2apache2mpmpreforkapache2utils
libexpat1sslcert
$sudoaptitudeinstalllibapache2modwsgi
$sudonano/etc/apache2/apache2.conf
8. Scrolldowntotheendofthefileandaddthefollowingcodeblock.Thensave
thefileandexit.
WSGIScriptAlias/mapproxy/mapproxy/config.py
WSGIDaemonProcessmapproxywsgidaemonprocesses=4threads=8
WSGIProcessGroupmapproxywsgidaemon
WSGIPythonHome/mapproxy/mapproxy
WSGIApplicationGroup%{GLOBAL}
<Directory/mapproxy>
OptionsAll
AllowOverrideAll
GoogleMapsforWork22/35
Requireallgranted
</Directory>
$sudoserviceapache2restart
9. AccessMapProxyviatheApachewebserverlisteningonport80:
http://YourIP/mapproxy/demo
Load balancing
WrappingservicessuchasWMSandWMTStotilesstoredonGoogleCloudstorage
introducesoverhead.WhenaWMSrequestcomesin,MapProxyhastodownloadthetiles
fromCloudStoragethatintersectwiththerequestedboundingbox,compositethem,andthen
cutthemintoasinglenewimage.UnlikeCloudStorage,MapProxyrunningonaCompute
EngineVMis,bydefault,notdesignedtohandleveryhighQPSorsupportnumeroususers
simultaneously.Forthisreason,werecommendthatyouincorporateloadbalancing.
GoogleMapsforWork23/35
ForafewuserswhooccasionallyuseyourOGCservices,youmightbeabletohavejustone
VMrunninghowever,youllneedtheabilitytoscaletohandlehigherdemand.Compute
Engineoffersmanywaystoconfigureloadbalancingthisdocumentshowsanetworkload
balancedapproachwithautoscaling.
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickSnapshots.
2. ClickNewsnapshot.
3. Givethesnapshotaname,andchoseyourworkingVMasthesourcedisk.Thenclick
Create.
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickDisks.
2. ClickNewdisk.
GoogleMapsforWork24/35
3. Givethenewdiskaname,andchosethezoneinwhichyoudlikethedisktoreside.
ThisshouldbethesameasthezonewhereyoudliketorunyourVMs.
FortheSourceType,choseSnapshot,andthenchosethesnapshotyoucreatedin
thepreviousstepasthesource.ThenclickCreate.
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickImages.
2. ClickNewimage.
GoogleMapsforWork25/35
3. Givetheimageaname,andchoseDiskastheSourceType.Selectthediskyou
createdinthepreviousstepasthesourcedisk.ThenclickCreate.
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickInstance
templates.
2. ClickCreateaninstancetemplate.
GoogleMapsforWork26/35
3. Givetheinstancetemplateaname,andsetthefirewalltoallowHTTPtraffic.
4. Chosethemachinetype.A2CPUmachineisagoodbalancebetweenpriceand
performance.ItshouldallowyourloadbalancedVMstohandleseveralsimultaneous
connectionspermachine,whilealsobeinglessexpensivethanahighCPUmachine.
5. ForImageforthetemplate,choosetheimageyoucreatedinthepreviousstep.For
theDisktype,choseastandardpersistentdisk.
GoogleMapsforWork27/35
1. FromtheComputeEnginelistintheDevelopersConsole,clickInstancegroups.
2. ClickCreateanewinstancegroup.
3. Givetheinstancegroupaname,andchosetheinstancegrouptemplateyou
previouslyconfigured.
4. TurnonAutoscaling,andchosetoautoscalebasedonHTTPloadbalancingusage.
Acceptthedefaultvalueof80%.
Later,wellconfiguretheRateofRequestspersecond(RPS/QPS),whichsays,
Whenmyloadbalancerisreceiving80%oftheRPSthatthecurrentnumberof
instancescansupport,spinupanewinstance.
5. Configureaminimumof1instance,andsetalimitforthemaximumamountof
instancesyourewillingtoallowtobecreated.Formostcases,10to20issufficient.
GoogleMapsforWork28/35
GoogleMapsforWork29/35
1. FromtheComputeEnginelistintheDevelopersConsoleproject,clickHTTPload
balancing.
2. ClickCreateanHTTPloadbalancer.
3. Givetheloadbalanceraname.ThenclickCreate.
4. Oncetheloadbalanceriscreated,clickthedefaultbackendservicetoeditit.
GoogleMapsforWork30/35
5. Forthebackendservice,chosetheinstancegroupyoupreviouslycreated.Forthe
balancingmode,choseRate,andforMapProxy,5RPSisappropriateforeachofour
n1standard2virtualmachines.Becauseyoupreviouslyselected80%asourHTTP
LoadBalancingUtilizationthreshold,onceyourfirstinstancestartsreceivinga
sustained4RPS,anewinstancewillbecreated.Oncethetwoinstancesreach8
RPS,athirdinstancewillbecreated,andsoon,untiltheupperlimitofthenumberof
instancesyouveconfigured.
6. Oncethebackendserviceisconfigured,clickthedefaulthealthchecklink.
GoogleMapsforWork31/35
TheHTTPLoadBalancerwillrunahealthchecktomakesurethatallyourinstance
groupsarehealthyandrespondingtorequests.Bydefault,itwilljustloadtherootof
yourwebservers.
7. TomakesurethatthehealthcheckisactuallyinvokingtheWSGIapplicationof
MapProxy,changethePathto/mapproxy/demo/Also,changetheIntervalto20
seconds.
GoogleMapsforWork32/35
8. ClickSaveandreturntotheHTTPLoadBalancerUI.ThenclickAddaglobal
forwardingrule.
GoogleMapsforWork33/35
9. Givetheruleaname,andchoseeitheranEphemeralorStaticIP.Werecommend
choosingStaticIP,becauseyoullsharethisIPaddresswithusersormapittoa
customURL.
10. ClickCreate.
YourHTTPloadbalancerandinstancegroupswillbepushedtoproduction.
Astheserviceisbeingturnedon,youllseea404erroratyourephemeralorstaticIP
address/mapproxy/demo/.
Shortlyafter,youllstarttosee500errorsduringtheDNSpropagationphase.
GoogleMapsforWork34/35
Afterabout5minutes,theserviceandDNSpropagationshouldbecomplete,and
youllseeyourliveGoogleComputeEngineMapProxyService.Yourservicereadyto
serveatGooglescale,withHTTPloadbalancing,autoscaling,andtheabilitytocreate
OGCendpointsaroundtilesservedfromGoogleCloudStorage.
Seethedemo
GoogleMapsforWork35/35