Mule Architecture - MuleSoft
Mule Architecture - MuleSoft
Mule Architecture - MuleSoft
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Mule</strong> <strong>Architecture</strong><br />
Eugene Ciurana<br />
eugenex@mulesoft.com<br />
http://eugeneciurana.com/contact
About Eugene...<br />
• 15+ years building mission-critical,<br />
high-availability systems<br />
• 14+ years Java work<br />
• Open source evangelist<br />
• Official adoption of open source/<br />
Linux at Walmart worldwide<br />
• State of the art tech for main line of<br />
business roll-outs<br />
• Largest companies in the world<br />
• Retail<br />
• Finance<br />
• Oil<br />
• Background: robotics to on-line retail
<strong>Mule</strong> As Your<br />
SOA/ROC Hub
What is the Problem<br />
Very tight deadlines<br />
• Typical 12-month project rolled out in 90 days<br />
Development team built at the same time as application<br />
design work<br />
No history of developing Web applications<br />
Rigid IT infrastructure and policies<br />
• SOX and other compliance issues<br />
• IT guys used to rule the world<br />
Integration with financial and other legacy systems is a<br />
must
Integration Through Services<br />
SOA = Services-Oriented <strong>Architecture</strong><br />
Collection of services that communicate with one<br />
another<br />
• No dependencies on other services<br />
• Self-contained<br />
Messaging: mechanism for communication between<br />
two or more services<br />
Real-time, asynchronous, synchronous<br />
• May occur over different transports<br />
HTTP, FTP, JMS, RMI, CORBA, etc.
SOA Limitations<br />
Not all systems can be mapped as services<br />
Workflow issues<br />
Development team coordination<br />
Programmer skill levels<br />
• Do your programmers grok SOA<br />
System coupling<br />
• System dependencies<br />
• Organizational dependencies
Environment - First Iteration<br />
External<br />
Device<br />
PC<br />
application<br />
Web<br />
browser<br />
SOAP REST<br />
http<br />
http<br />
Internet<br />
SOAP<br />
REST<br />
thesite.com<br />
Java 6<br />
Wicket<br />
CMS<br />
feed<br />
Microsite<br />
SOAP<br />
REST<br />
<strong>Mule</strong> ESB<br />
SOAP REST<br />
Dedicated Store<br />
Java 6, Wicket, Tomcat,<br />
etc.<br />
Cart,<br />
session<br />
data<br />
SOAP<br />
REST<br />
SOAP<br />
REST<br />
SOAP<br />
REST<br />
SOAP<br />
REST<br />
SOAP REST<br />
Firewall<br />
<strong>Mule</strong> ESB<br />
SOAP, REST, JMS, MQ, BPEL, JDBC, caching, in-memory<br />
REST<br />
CRM<br />
JDBC REST<br />
Merchandizin<br />
g<br />
Tools<br />
CMS<br />
Content<br />
Repository<br />
Customer<br />
Master<br />
ERP<br />
Crowd Single Sign-On<br />
Active<br />
Directory<br />
(domain)<br />
Custom
Technologies Deployed<br />
Best of Breed<br />
<strong>Mule</strong> ESB - the backbone<br />
Crowd Single Sign-on<br />
GWT for front end AJAXy stuff<br />
Wicket for Web applications<br />
Day Communiqué / CRX for CMS<br />
All open-source development tools<br />
Java 5 and Java 6
How Well Did This Work
What Happened Next<br />
Integration of third-party systems<br />
• 2007 - two<br />
• 2008 - ten or more<br />
International sites<br />
Real-time device data processing<br />
Multiple data sources<br />
• Databases<br />
• Financial systems<br />
• CRM<br />
Support for millions of devices “in the wild”
Millions of Devices
Millions of Devices!
Shift Toward Consuming Resources<br />
Conscious decision to blur the distinction between<br />
“services” and “data sources”<br />
Everything is a resource<br />
• SOAP, REST, JMS, files<br />
• Web apps back-end<br />
• Computational data<br />
Resources are available through a well-defined<br />
protocol<br />
Resources are always available through a common<br />
transport to simplify development and deployment
What Is Resource-Oriented Computing<br />
All components of a system are viewed as resources to be<br />
consumed synchronously or asynchronously<br />
There is no distinction between “data”, “objects” or<br />
“services”<br />
There is no dependency on a programming language or<br />
framework<br />
• Mix and match is the reason why you want to move toward ROC<br />
Resources are located through URIs<br />
Software identifies resources through logical rather than<br />
physical mappings
What Is Resource-Oriented Computing<br />
Programs map logical and physical locations through<br />
identifiers in traditional computing models<br />
• String resource = “I am some useful, non-trivial text.”;<br />
ROC defines resources through verbs and logical<br />
identifiers<br />
• Yes, it sounds like REST<br />
An identifier ALWAYS returns the CURRENT<br />
representation of a resource<br />
Each logical identifier is resolved for every request<br />
• Resource implementations can change dynamically, resource consumers<br />
need not care about where or how a resource is implemented
Java vs. REST vs. ROC<br />
Java REST ROC<br />
Identifier<br />
private int nX; URI URI<br />
Fetch<br />
out.printf(“nX =<br />
Method GET<br />
Protocol fetch<br />
%d\n”, nX);<br />
URI<br />
+ URI<br />
Resolve<br />
Compiler,<br />
DNS + app<br />
ROC kernel or<br />
reflection<br />
server<br />
backbone<br />
Compute<br />
Java Virtual<br />
App server<br />
Endpoint and<br />
Machine<br />
service object<br />
Low-level<br />
JVM, method,<br />
HTTP method +<br />
Verb + URI pair<br />
operation<br />
initializer<br />
URI
Defining Resources<br />
Resources don’t exist in the context of an application<br />
until they are requested<br />
Resources lack typing<br />
• Typing is relevant only to the consumer<br />
Endpoint URIs may convert types for individual data<br />
elements or complex data structures<br />
URIs may encode the desired operation to perform on<br />
the data<br />
• protocol://servername/subsystem/operation/resource
Resource Abstractions<br />
http://server/mycompany/promotions/product_catalogue<br />
The promotions resources may be generated...<br />
• cron periodically<br />
• On-demand<br />
• Aggregated<br />
The promotions system of record is independent of the<br />
ROC platform or the consumer<br />
The “verb” here is “promotions”, when combined with a<br />
GET<br />
There may be two or more aggregators that produce the<br />
resource
Resource Abstractions<br />
METHOD GET<br />
http://server/mycompany/promotions/product_catalogue<br />
Real-time<br />
Servlet<br />
HTTP Server<br />
Pervasive<br />
Reporting<br />
Database<br />
CMS
ROC Platforms<br />
Full ROC platform by 1060 Research<br />
• Custom distributed kernel<br />
GridGain, GigaSpaces<br />
• Distributed Computing<br />
Homebrew ROC<br />
VENDOR LOCK-IN!!!!<br />
• Are you in the business of building one from scratch<br />
Off-the-shelf integration<br />
• Best-of-breed strategy: find the best components and integrate<br />
them
ROC <strong>Architecture</strong><br />
The systems are built around a backbone that provides<br />
resources via URI<br />
The backbone acts as an resource container or as a<br />
conduit between resources or resources and consumers<br />
URI mapping is done by the backbone<br />
Resource containers can exist in the same memory space<br />
as the backbone or in a separate system<br />
Resource providers may be written in any programming<br />
language<br />
Resource providers are stateless
ROC <strong>Architecture</strong><br />
Modularity is attained through logical separation of<br />
resources<br />
• Resource providers as .jar, .war, or other entity<br />
• Localized backbones<br />
• Localized resource providers<br />
Logical separation may obey organizational policy,<br />
technology policy, or both<br />
Implementation can be done with off-the-shelf<br />
components in any combination that makes sense, as<br />
long as the backbone is protocol-, language-, and<br />
vendor-independent
ROC <strong>Architecture</strong><br />
Backbone: <strong>Mule</strong> ESB<br />
• Provides full independence from the kind of crap that vendors like to create<br />
lock-in for<br />
• Open-source<br />
• Workflow, transactions, transformations, logging, routing<br />
Resource container: <strong>Mule</strong> ESB<br />
• UMOs (service objects) implement business logic independently of protocol<br />
or data formats by design<br />
• Transactional, app server and workflow logic built-in<br />
• UMOs are just POJOs<br />
Synchronization<br />
• In-memory endpoints
ROC <strong>Architecture</strong><br />
Original architecture had lots of best-of-breed software<br />
• Tomcat<br />
• Dedicated application/service providers<br />
• Web servers<br />
ROC architecture only has two basic building blocks<br />
• <strong>Mule</strong> acting as a resource service provider (i.e. <strong>Mule</strong> is the application<br />
container)<br />
• UMOs as computationally active entities<br />
Existing and off-the-shelf systems plug into the<br />
architecture through SOAP, REST, JMS, etc.<br />
<strong>Mule</strong> allows us to define our own protocols, if necessary!
ROC <strong>Architecture</strong><br />
Service<br />
Provider<br />
(UPS, FedEx)<br />
Service Object<br />
Web<br />
browser<br />
Internet<br />
Remedy<br />
Dedicated API<br />
business logic<br />
Web app<br />
JMS, SOAP, etc.<br />
GUI<br />
App<br />
Transformer<br />
Transformer<br />
<strong>Mule</strong> ESB<br />
Transformer<br />
SOAP<br />
JDBC<br />
HTTP, XML<br />
CRM<br />
Product<br />
Catalogue<br />
Product<br />
Support<br />
Product<br />
Pages<br />
Support<br />
Product<br />
Pages<br />
Support<br />
Pages<br />
TCP pass-through<br />
Single Sign-On<br />
LDAP, SOAP<br />
Mainframe / RACF<br />
Active<br />
Directory<br />
Legacy<br />
Auth
ROC Implementation<br />
Dedicated protocols<br />
• vm://mycompany/subsystem/resource_name<br />
• http://mycompany/subsystem/resource_name<br />
Easy to extend to handle ROC:<br />
verb:protocol://mycompany:port/organization/subsystem/resource_name<br />
Easy to implement!
ROC Implementation<br />
Service Object<br />
CRM<br />
Product<br />
Catalogue<br />
Remedy<br />
business logic<br />
Web app<br />
SOAP<br />
JDBC<br />
Dedicated API<br />
JMS, SOAP, etc.<br />
<strong>Mule</strong> ESB Resource Service Provider<br />
SOAP<br />
JDBC<br />
Dedicated API<br />
JMS, SOAP, etc.<br />
Transformer<br />
Transformer<br />
Transformer<br />
<strong>Mule</strong> ESB Backbone<br />
Consumer Consumer Consumer Consumer Consumer
ROC Implementation<br />
Resource providers<br />
• SOAP API to CRM<br />
• JMS API to transactional pieces<br />
• Download app repository<br />
• OpenLaszlo dynamic rich Internet application provider<br />
Interfaces to existing systems<br />
• Epsilon direct mail interfaces<br />
• FTP, sftp, other data transfer<br />
Computational resources for ad hoc new functionality<br />
• MapReducers (2008, 2009)
ROC Implementation<br />
MapReduce<br />
controller<br />
assign<br />
notify<br />
<strong>Mule</strong> ESB<br />
bucket<br />
bucket<br />
bucket<br />
bucket<br />
bucket<br />
MapReduce<br />
map(f, l)<br />
MapReduce<br />
map(f, l)<br />
MapReduce<br />
map(f, l)<br />
assign<br />
Terracotta<br />
assign<br />
notify<br />
MapReduce<br />
reduce(f, l)<br />
MapReduce<br />
reduce(f, l)<br />
Output<br />
Output<br />
bucket<br />
MapReduce<br />
map(f, l)<br />
Virtual Servers<br />
(Xen, Zones)
Implementation Options<br />
Build one from scratch<br />
Use an existing distributed processing network<br />
• Hadoop - open-source<br />
• GigaSpaces - distributed processing, transaction support<br />
• GridGain<br />
Build a system from components that already exist in your<br />
infrastrcture<br />
• Programmers use tools they already know<br />
• No additional time or resource demands form production IT staff<br />
• Management views adoption as an evolution of existing systems - easier<br />
adoption
Real Life Example<br />
Trades analysis for a large financial institution<br />
• Stock trades<br />
• Commodities<br />
• Near real-time<br />
Objective: Replace an expensive, commercial database<br />
used today for a similar purpose<br />
Implementation:<br />
• Trading systems use the <strong>Mule</strong> Integration Platform as its backbone<br />
• No disruption to existing business processes<br />
• Use Hadoop/HDFS<br />
• Integrate <strong>Mule</strong> and Hadoop
Real Life Example<br />
Show the issues that need to be addressed by a<br />
MapReduce system<br />
Uses the <strong>Mule</strong> integration platform because...<br />
• Thread/process dispatching is easy to do<br />
• It uses POJOs for the implementation<br />
• I/O subsystems are “free” and independent of the business logic<br />
The Processor Farm can take various forms:<br />
• In-box: Niagara processor, 32-concurrent threads support, all data mapping<br />
and transfers occurs in memory<br />
• Traditional processor farm: single- or dual-core systems connected over a<br />
fast LAN<br />
• Hybrid processor farm: physical farm of multi-core systems over fast LAN
Real Life Example
Real Life Example<br />
USB<br />
End-User System (Mac, Windows)<br />
LeapFrog<br />
Connect<br />
Web<br />
Browser<br />
Third-party<br />
Partner Site<br />
S3<br />
Content<br />
Repository<br />
Internet<br />
www.leapfrog.com<br />
connected<br />
products<br />
LearningPath<br />
Firewall<br />
<strong>Mule</strong> ESB backbone<br />
HTTP, SOAP (CXF), REST, etc. routing, filtering, and dispatching; ActiveMQ JMS broker; dedicated LeapFrog services<br />
<strong>Mule</strong> ESB tailbone<br />
Connected products SOAP, REST web<br />
services<br />
<strong>Mule</strong> ESB funnybone<br />
Device log upload, processing, servlet<br />
container<br />
Content<br />
Management<br />
System<br />
REST, JCR<br />
Crowd SSO<br />
Customer<br />
Data<br />
Game<br />
play<br />
Data<br />
Servlets<br />
App Logic<br />
Device<br />
Logs<br />
Content<br />
Authoring<br />
User<br />
Credentials
Real Life Example<br />
Internet<br />
Load Balancer<br />
Application<br />
Server<br />
Tomcat 6<br />
Services Proxy<br />
Application<br />
Server<br />
Tomcat 6<br />
Load Balancer - Backbone<br />
Backbone - message filtering, routing, dispatching, queuing, events<br />
<strong>Mule</strong> ESB<br />
1.6.2<br />
<strong>Mule</strong> ESB<br />
1.6.2<br />
<strong>Mule</strong> ESB<br />
1.6.2<br />
<strong>Mule</strong> ESB<br />
1.6.2<br />
Load Balancer - Tailbone<br />
Load Balancer - Funnybone<br />
Load Balancer - Message Broker<br />
<strong>Mule</strong> ESB<br />
SOAP, REST<br />
<strong>Mule</strong> ESB<br />
SOAP, REST<br />
<strong>Mule</strong> ESB<br />
servlet, MTOM<br />
<strong>Mule</strong> ESB<br />
servlet, MTOM<br />
ActiveMQ<br />
ActiveMQ<br />
Database<br />
NFS<br />
share<br />
NFS<br />
share
Production Systems
Rolling Out to Production<br />
No situation is entirely unique, nor are all deployments alike<br />
There is no “best way” - there is only “best way for this situation”<br />
Standalone vs. embedded <strong>Mule</strong> deployment<br />
Advantages<br />
Disadvantages<br />
Technologies: ESBs, clouds, mini-clouds, Java, App Engine, etc.<br />
How cloud services lower costs for the enterprise<br />
Understanding the advantages of<br />
• Deployment on the cloud<br />
• Hybrid deployment between the cloud and the enterprise
ESB Applications<br />
* Application logic is implemented via stateless services<br />
* The services run in <strong>Mule</strong> as the application container - no application server necessary<br />
* RESTful services are easier to code than SOAP - no schema validation<br />
* Suggested data exchange format: JSON for simplicity, XML for faster integration<br />
* Stateless services are easier to cluster<br />
* Stateless services permit easier upgrades and changes<br />
* Stateless services scale better<br />
Existing App Server (JBoss)<br />
batch processing via queues<br />
RESTful Web Service<br />
RESTful Web Service<br />
http://server_name/service_1<br />
http://server_name/service_3<br />
<strong>Mule</strong> ESB as Application Container<br />
App logic built with aggregated services<br />
Service 1 Service 2 Service 3<br />
vm://service_2<br />
vm://service_3
Application Components<br />
* Green items = code for the application<br />
* Everything else = <strong>Mule</strong> standard services<br />
* App is written in 100% Pure Java, no <strong>Mule</strong>-specific code for maximum portability<br />
* Transformers may have <strong>Mule</strong> API calls<br />
application<br />
HTTP2Payload<br />
Converts HTTP request<br />
to an object<br />
http://server.company.com/service_call<br />
HTTP<br />
request<br />
Payload<br />
* Transformers can have country-specific logic<br />
* Modules can have country-specific logic<br />
Bad request<br />
Claims System Module<br />
Payload<br />
HTTP<br />
response<br />
Payload2HTTP<br />
Converts the payload<br />
to HTTP response<br />
local<br />
database<br />
Application<br />
Bad response<br />
= application-specific item
Portable, Reusable Code<br />
* Modules written in Java can be used in <strong>Mule</strong> or in JBoss without changes<br />
* JBoss components require wrapping in JEE<br />
* JBoss can talk to <strong>Mule</strong> apps and vice versa<br />
* Legacy system can stay in JBoss, new functionality in <strong>Mule</strong>, or vice versa<br />
JBoss App Server<br />
JBoss-specific, JEE wrapper<br />
Claims System Module<br />
<strong>Mule</strong> ESB as App Container<br />
Claims System Module<br />
Application<br />
Application<br />
jdbc://server/claims_db<br />
Application<br />
<strong>Mule</strong> talks to databases<br />
or other resources via<br />
code API or via endpoints<br />
local<br />
database<br />
local<br />
database<br />
= application-specific item
Clustering<br />
* Two or more <strong>Mule</strong> instances can provide services, for scalability if there is high demand<br />
* Load balanced configuration has built-in fail-over<br />
* External apps see a single point of entry: the service endpoint name<br />
* Load balancer or proxy sends the request to any available <strong>Mule</strong> server<br />
* Increased demand - add another <strong>Mule</strong> server without interrupting the existing ones<br />
* Decreased demand - remove <strong>Mule</strong> servers without interrupting other servers<br />
* This is an active/active configuration - any server can handle a request at any time<br />
* Assumes that the service application components are stateless<br />
External Applications<br />
http://server.mycompany.com/service_call<br />
Load<br />
Balancer<br />
http://mule_server_1/service_call<br />
http://mule_server_2/service_call<br />
<strong>Mule</strong> ESB as Application Container 1<br />
<strong>Mule</strong> ESB as Application Container 2<br />
Service 1 Service 2 Service 3<br />
Service 1 Service 2 Service 3
ESB Application Failover<br />
* A/A configuration uses the load balancer to dispatch service calls<br />
* The load balancer takes a failing service out of rotation automatically<br />
* Failure reason no. 1: network connectivity<br />
* Failure reason no. 2: <strong>Mule</strong> container<br />
* Failure reason no. 3: Service application bug<br />
External Applications<br />
http://server.mycompany.com/service_call<br />
Load<br />
Balancer<br />
http://mule_server_1/service_call<br />
http://mule_server_2/service_call<br />
<strong>Mule</strong> ESB as Application Container 1<br />
<strong>Mule</strong> ESB as Application Container 2<br />
Service 1 Service 2 Service 3<br />
Service 1 Service 2 Service 3
Uninterrupted Application Updates<br />
* Allow stopping and deploying new application functionality without stopping services<br />
* Allow upgrades to a country's configuration without affecting other countries or stopping services<br />
Load Balancer<br />
<strong>Mule</strong> ESB as Application version 1.4 <strong>Mule</strong> ESB as Application version 1.4<br />
Load Balancer<br />
<strong>Mule</strong> ESB as Application version 2.0 <strong>Mule</strong> ESB as Application version 1.4<br />
time<br />
Load Balancer<br />
<strong>Mule</strong> ESB as Application version 2.0 <strong>Mule</strong> ESB as Application version 1.4<br />
Load Balancer<br />
<strong>Mule</strong> ESB as Application version 2.0 <strong>Mule</strong> ESB as Application version 2.0
Production Readiness<br />
Production<br />
QA<br />
.Net Server<br />
services<br />
HTTP other<br />
proxy<br />
.Net Admin<br />
App Server<br />
.Net App<br />
Server<br />
.Net Server<br />
services<br />
HTTP other<br />
proxy<br />
.Net Admin<br />
Server<br />
.Net App<br />
Server<br />
CDN<br />
CDN<br />
CDN<br />
.Net Server<br />
CDN<br />
CDN<br />
CDN<br />
IRC<br />
Services<br />
Services<br />
services<br />
HTTP other<br />
proxy<br />
Load<br />
balancer<br />
Databases<br />
Staging<br />
Load<br />
balancer<br />
Services<br />
.Net Admin<br />
App Server<br />
Services<br />
Deployment<br />
Databases<br />
.Net App<br />
Server<br />
Deployment<br />
Continuous Integration Server<br />
Version Control System, Automatic Builds, Unit Tests<br />
Deployment<br />
.Net Server<br />
Deployment<br />
CDN<br />
CDN<br />
CDN<br />
CDN<br />
services<br />
HTTP other<br />
proxy<br />
IRC<br />
Development<br />
IRC<br />
Services<br />
.Net Admin<br />
Server<br />
Services<br />
Databases<br />
.Net App<br />
Server<br />
Databases<br />
IRC<br />
Databases<br />
Developer 0 Developer 1 Developer 2 Developer 3
Database Replication<br />
Primary Cluster<br />
Node 0 Node 1<br />
ESB as app services provider<br />
Partition 0<br />
Partition 1<br />
DB 0<br />
DB 1<br />
DB 0b<br />
DB 1b
Real Life Example<br />
• Large consumer and services company<br />
• .Net / Windows servers infrastructure<br />
• ASP.Net<br />
• SQL Server<br />
• Two-tier architecture<br />
• The system “just grew” and became a business<br />
• Server pages, services, media<br />
• 6-month scalability project began in April<br />
• Implementation complete 25.Sep of the same year
Real Life Example<br />
• System grew “as needed” - no planning<br />
• Combines end-user and internal applications in the same<br />
server<br />
• It only scales vertically -- and not very well<br />
• Applications and database are tightly coupled<br />
• Application servers and services tightly coupled<br />
• Single environment: from development to production<br />
without passing Go nor collecting $200<br />
• Disaster recovery<br />
• 4 hours minimum<br />
• From (stale) backups
Real Life Example<br />
• Introduces a CDN for asset delivery<br />
• Amazon S3 (optional Cloud Front) for asset delivery<br />
• Reduces load on company servers and bandwidth costs<br />
• Introduces database replication for production<br />
environments<br />
• Establishes a continuous integration environment<br />
• Set tools for hybrid UNIX/Windows environment<br />
• UNIX tools take precedence; Cygwin everywhere<br />
• Improved build/release process
Real Life Example<br />
Client<br />
Client<br />
Client<br />
Client<br />
Zone Server<br />
UDP<br />
Services UDP<br />
Windows Services UDP<br />
Windows Services<br />
Windows<br />
rsync<br />
Linux<br />
Internet<br />
Master, IRC<br />
Linux<br />
Services<br />
.Net<br />
Applications<br />
.Net<br />
SQL<br />
Server
Cloud Deployment<br />
• Web applications move to a uniform technology (.Net)<br />
• The database and stored procedures are normalized and<br />
optimized<br />
• Applications use common resources via <strong>Mule</strong> ESB and<br />
services<br />
• No more direct calls from apps to databases<br />
• Business logic is implemented as stateless POJOs<br />
• Software stack is “best of breed”<br />
• Windows, other servers driven by business requirements<br />
• Open source software wherever possible
Cloud Deployment<br />
• Web and other RPC services must coexist<br />
• Different partners use different protocols<br />
• <strong>Mule</strong> transformers take care of all the interfaces so that<br />
development may scale / continue independently of what<br />
happens in other layers<br />
• Bandwidth can be expen$ive!<br />
• Data exchange protocols<br />
• Clients: custom, XML, JSON<br />
• Images: HTTP, S3<br />
• Cloud-to-HQ: custom, XML/SOAP, protocol buffers<br />
• HQ data centre: XML/SOAP, protocol buffers<br />
• Replication strategy: data centre<br />
• The cloud isn’t trustworthy yet
Cloud Deployment<br />
• Deployment involves using an Amazon Machine Image<br />
(AMI)<br />
• Use existing ones from Amazon or third parties<br />
• Configure your own to meet your software requirements<br />
• AMIs need a post-configuration step in a load-balanced<br />
environment<br />
• Unique file processing (/etc/hosts, /etc/hostname, app<br />
configuration, etc.)<br />
• Necessary intermediate step between launching the AMI and<br />
having a useful machine<br />
• Elastic Load Balancer and Elastic IP limitations<br />
• ELB only works for dynamic IP addresses<br />
• ELIPs are limited to 5 per account
Cloud Deployment<br />
legacyservices01<br />
10.246.98.160<br />
legacyservices02<br />
10.246.103.196<br />
10.253.223.150<br />
services01<br />
10.252.127.65<br />
services02<br />
10.252.185.237<br />
master01<br />
10.252.186.230<br />
174.129.238.159<br />
master02<br />
10.252.71.195<br />
master1ny<br />
services<br />
syncserver01<br />
10.252.126.134<br />
10.252.182.83<br />
syncserver<br />
database<br />
master<br />
10.246.99.143<br />
database<br />
slave<br />
10.246.74.31<br />
10.252.70.149<br />
web01<br />
10.246.78.162<br />
10.252.125.90<br />
web02<br />
10.246.78.180<br />
los01<br />
10.246.99.160<br />
10.252.127.143<br />
los02<br />
10.246.102.295<br />
losgamesvr01<br />
10.246.98.102<br />
10.253.191.195<br />
losgamesvr02<br />
10.246.106.101<br />
edportal01<br />
FRONT END<br />
10.246.102.178<br />
10.253.191.22<br />
edportal02<br />
FRONT END<br />
10.246.102.113<br />
syncserver02<br />
10.252.125.209<br />
174.129.238.110<br />
174.129.238.126<br />
174.129.238.129<br />
174.129.238.145<br />
174.129.238.184<br />
174.129.238.189<br />
replicate<br />
174.129.239.18<br />
174.129.239.11<br />
10.252.182.128<br />
World<br />
edportal01<br />
SERVICES<br />
10.246.99.212<br />
10.253.138.195<br />
edportal02<br />
SERVICES<br />
10.246.102.64<br />
174.129.239.41<br />
downloads<br />
S3<br />
174.129.238.188<br />
DNS<br />
174.129.15.199<br />
edportalsrvc<br />
legacyservices<br />
database<br />
web<br />
los<br />
losgames<br />
edportal<br />
mastergameserver01 mastergameserver02<br />
game server<br />
174.129.239.45<br />
game server<br />
174.129.239.67<br />
game server<br />
174.129.239.68<br />
game server<br />
174.129.239.81<br />
174.129.24.40<br />
maingamerepos<br />
mailservices<br />
10.252.170.69<br />
174.129.25.145
Cloud Deployment<br />
Traditional Hosted Environments<br />
Setup Monthly Bandwidth Total / year<br />
Production $1,300 $5,5580 $2,000 $70,260<br />
Staging $1,300 $5,5580 $ 0 $68,260<br />
QA $ 600 $1,450 $ 0 $18,000<br />
Dev $ 600 $1,450 $ 0 $18,000<br />
Total $174,520
Cloud Deployment<br />
Amazon EC2 Configuration<br />
Setup Monthly Bandwidth Total / year<br />
Production $ 0 $4,320 $1,200 $66,240<br />
Staging $ 0 $4,320 $ 0 $51,840<br />
QA $ 0 $1,080 $ 0 $12,960<br />
Dev $ 0 $ 0 $ 0 $ 0<br />
$43,000 cheaper<br />
Total $131,040
Final Configuration - June 2010<br />
World<br />
web<br />
174.129.238.110<br />
10.252.125.90<br />
master1ny<br />
mastergameserver01<br />
174.129.25.145<br />
mailservices<br />
10.252.170.69<br />
174.129.238.184<br />
all web<br />
properties<br />
web01<br />
all web<br />
properties<br />
web02<br />
all web<br />
properties<br />
web03<br />
all web<br />
properties<br />
web04<br />
master01<br />
10.252.186.230<br />
downloads<br />
S3<br />
174.129.15.199<br />
DNS<br />
services<br />
174.129.238.159<br />
10.252.182.128<br />
174.129.238.189<br />
10.252.182.83<br />
syncserver<br />
services01<br />
legacy games<br />
Ed Portal<br />
Scalable Services<br />
services02<br />
legacy games<br />
Ed Portal<br />
Scalable Services<br />
services03<br />
legacy games<br />
Ed Portal<br />
Scalable Services<br />
services04<br />
legacy games<br />
Ed Portal<br />
Scalable Services<br />
syncserver01<br />
10.252.126.134<br />
174.129.24.40<br />
syncserver02<br />
10.252.125.209<br />
174.129.239.45<br />
game<br />
servers<br />
maingamerepos<br />
174.129.239.67<br />
game<br />
servers<br />
174.129.239.18<br />
10.252.70.149<br />
database<br />
174.129.239.68<br />
game<br />
servers<br />
database<br />
master<br />
10.246.99.143<br />
replicate<br />
database<br />
slave<br />
10.246.74.31<br />
174.129.239.81<br />
game<br />
servers
<strong>Mule</strong> Punching
Scripting<br />
• Scripting is built into Java 6<br />
• Spring has limited dynamic language support<br />
• <strong>Mule</strong> ESB, ServiceMix, other spring containers offer better or worse<br />
support on top of Spring; read the documentation<br />
• Mix and match scripting language features and standard<br />
Java!!!<br />
• If your container or app don’t support your chosen language<br />
it’s easy to extend it<br />
• Take a look at the javax.script package<br />
• Is this popular You bet!<br />
• At least 40 languages supported<br />
• Most run on the JVM itself<br />
• Python, Ruby, awk, JavaScript, Groovy, Scheme, Scala run as bytecodes<br />
• Some use a JNI bridge between Java and the native scripting engine
Scripting<br />
• Rapid prototyping<br />
• Better tools in some problem domain<br />
• Python: outstanding system management tools<br />
• awk: runs circles around Java for massive text processing<br />
• Groovy: fast Java prototyping<br />
• You get the idea<br />
• Missing features in the Java language<br />
• Generators and comprehensions<br />
• Continuations<br />
• Everything is an object and introspection<br />
• Dynamic event handling<br />
• Leverage domain expertise<br />
• Long learning curve for Java coders in new problem domain<br />
• Domain experts may have robust, mature code written in other<br />
languages<br />
• It’s FUN
When to Avoid Scripting<br />
• Performance<br />
• The JVM, the JIT, and Java are optimized to work together<br />
• Scripting languages, even when compiled to .class, will run<br />
slower<br />
• Resource consumption<br />
• Java library + scripting language’s library<br />
• Threading Java’s threads are superb<br />
• Type safety may be critical<br />
• Completeness<br />
• Java’s language shortcomings are often overcome by its superb<br />
class libraries
How Does Your Language Rate<br />
• TIOBE Programming Language Index (March 2010)<br />
1 Java<br />
2 C<br />
3 PHP<br />
4 C++<br />
5 Visual BASIC<br />
6 C#<br />
7 Python<br />
8 Perl<br />
9 Delphi<br />
10 JavaScript<br />
11 Ruby<br />
JVM
Selection Criteria<br />
• Java was cumbersome for some low-level requirements<br />
• The language and class library are rich<br />
• The abstractions weren’t appropriate for problem domain<br />
• Rich class library and ecosystem<br />
• Portability across many heterogeneous platforms<br />
• Language stability and robustness<br />
• Stand-alone and JVM implementations<br />
• Existing know-how<br />
The Java language is Awesome as long as<br />
you don’t need to break its abstractions!
Selection Criteria<br />
• Outstanding support for system-level operations<br />
• Mid-level language preferred<br />
• Rich class library and ecosystem<br />
• Portability across many heterogeneous platforms<br />
• Language stability and robustness<br />
• Stand-alone and JVM implementations<br />
• Existing know-how<br />
Our choice:<br />
Python
Selection Criteria<br />
Excellent class library<br />
Excellent 3rd party support<br />
Great for writing robust apps<br />
Java<br />
Static Typing<br />
Verbose<br />
Faster Execution Time<br />
Slower Compile/Build/Test/Deploy Cycle<br />
Slower Development Time<br />
Harder to read<br />
Python<br />
Dynamic Typing<br />
Concise<br />
Slower Execution Time<br />
Faster Develop/Deploy Cycle<br />
Faster Development Time<br />
Easier to read
Java vs. Python Comparisons<br />
• Original payload (BSON or JSON):<br />
• { “name” : “Eugene”, “nCount” : 42 }<br />
• Dealing with the Java code:<br />
• Deserialize the JSON code to some Java object<br />
• MyObject o = (new Gson()).fromJson(payload, MyObject.class);<br />
• Forces to define a new type or go through some tedious<br />
specification<br />
• Requires annotations if using Jersey<br />
• Code, code, code, code and more code!<br />
• Dealing with Python code:<br />
• Deserialize to some Python object:<br />
• o = json.loads(payload)<br />
• Use the built-in dictionary as the payload (akin to a Map)<br />
• No need to define a new Java object or add all the extra code/<br />
annotations for type checking!
Java vs. Python Comparisons<br />
• Simple operation: insert new payload<br />
public ObjectId add(MyObject payload) {<br />
BasicDBObject o = new BasicDBObject();<br />
ObjectId oID = null;<br />
o.put(“name”, payload.getName());<br />
o.put(“nCount”, payload.getCount());<br />
docs.insert(o); // database collection “insert” persistent<br />
oID = docs.findOne(o).get(“_id”);<br />
}<br />
return oID;<br />
{ “name” : “Eugene”,<br />
“nCount” : 42,<br />
“_id” : { “$_oid” : “123456789abcdef426798efcafebabe” }<br />
}
Java vs. Python Comparisons<br />
• Simple operation: insert new payload<br />
def add(payload):<br />
objectID = None<br />
objectID = docs.insert(payload)<br />
return objectID<br />
{ “name” : “Eugene”,<br />
“nCount” : 42,<br />
“_id” : { “$_oid” : “123456789abcdef426798efcafebabe” }<br />
}
Java vs. Python Comparisons<br />
• Simple operation: Create a collection with elements from<br />
another.<br />
public List getNames() {<br />
List list = new ArrayList();<br />
for (MyObject record : someResultSet)<br />
list.add(record.getName());<br />
return list;<br />
} // getNames<br />
.<br />
.<br />
myNames = this.getNames();<br />
myNames = [ record.getName() for record in someResultSet ]
Java vs. Python Comparisons<br />
• Class library<br />
• The JSE and JEE class libraries are very complete<br />
• The Python libraries are almost equivalent almost 1:1<br />
• Less verbose<br />
• Third party libraries are equivalent<br />
• Our team realized that we could start writing the<br />
business logic entirely in Python<br />
• Use Java libraries where appropriate<br />
• Use Python libraries where appropriate<br />
• Don’t mix-n-match on the same class/object/module
Java vs. Python Comparisons<br />
3rd Party<br />
Monitoring<br />
Meta View, Security, and Integration<br />
Monitoring System<br />
Command<br />
Center (GUI)<br />
3rd Party<br />
Tools<br />
Services Engine<br />
Infrastructure<br />
Management Engine<br />
Configuration Interface<br />
Distributed<br />
Components<br />
Configuration<br />
Manager<br />
DB2<br />
DB1<br />
Python components or<br />
APIs or legacy code<br />
Java components or<br />
APIs or legacy code
Java vs. Python Comparisons<br />
3rd Party<br />
Monitoring<br />
Meta View, Security, and Integration<br />
Monitoring System<br />
Command<br />
Center (GUI)<br />
3rd Party<br />
Tools<br />
Services Engine<br />
Infrastructure<br />
Management Engine<br />
Configuration Interface<br />
Distributed<br />
Components<br />
Configuration<br />
Manager<br />
DB2<br />
DB1<br />
Python components or<br />
APIs or legacy code<br />
Java components or<br />
APIs or legacy code
<strong>Mule</strong> Services and Python<br />
• <strong>Mule</strong> is great for putting services together across<br />
multiple protocols<br />
• No OSGi support in 2.x<br />
• Tedious compile/build/package/deploy/test/run cycle<br />
• <strong>Mule</strong> is based on Spring<br />
• It has Dynamic Language Support<br />
• It’s more general and supports any scripting language<br />
conforming with JSR 223<br />
• Business objects and transformers can be implemented<br />
in any scripting language<br />
• These techniques can be applied to any ESB (e.g.<br />
ServiceMix) or Spring container<br />
• Easy to incorporate code written by non-Java coders<br />
into an enterprise app running on a JVM!
<strong>Mule</strong> Services and Python<br />
• We now have hot deployment without a long wait to<br />
restart the <strong>Mule</strong> container<br />
• No dicking around with .jars, bundles, activation,<br />
deactivation<br />
• Save a file, test the service in less than a second<br />
• Potentially patch production code in a hurry if necessary<br />
with no service disruption<br />
• Call standard Java libraries when needed<br />
• Integrate with <strong>Mule</strong> where appropriate using the <strong>Mule</strong><br />
API, otherwise keep it separate<br />
• Now we have modules and business logic that can run in<br />
a Java host or anywhere that Python works!
<strong>Mule</strong> Services and Python<br />
<strong>Mule</strong> libraries<br />
Code that can be modified<br />
at runtime<br />
Java libraries<br />
Code that can only be modified<br />
with a re-start<br />
Python libraries<br />
mulescript.py muleservice.py businessmodule.py<br />
service<br />
endpoints<br />
JBoss<br />
Component<br />
<strong>Mule</strong> ESB Services Host and Integration Platform<br />
other<br />
system<br />
Other <strong>Mule</strong><br />
Component<br />
Spring<br />
Component<br />
DB
<strong>Mule</strong> Services and Python<br />
<strong>Mule</strong> libraries<br />
Code that can be modified<br />
at runtime<br />
Java libraries<br />
Code that can only be modified<br />
with a re-start<br />
Python libraries<br />
mulescript.py muleservice.py businessmodule.py<br />
service<br />
endpoints<br />
JBoss<br />
Component<br />
<strong>Mule</strong> ESB Services Host and Integration Platform<br />
other<br />
system<br />
Other <strong>Mule</strong><br />
Component<br />
Spring<br />
Component<br />
DB
<strong>Mule</strong>/Spring Configuration<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Service Definition<br />
• This code is the interface between the <strong>Mule</strong>/Spring world<br />
and the Python world<br />
• Regardless of how complex the script gets, this pattern<br />
remains almost identical<br />
#!/usr/bin/env jython<br />
#<br />
# mulescript.py<br />
import article.muleservice<br />
from article.muleservice import Sample<strong>Mule</strong>Component<br />
reload(article.muleservice) # For mule punching<br />
sample = Sample<strong>Mule</strong>Component(payload,<br />
log, eventContext)<br />
result = sample.serviceRequest()
Service Implementation<br />
def serviceRequest(self):<br />
if self.eventContext is not None:<br />
self.payload = self.eventContext.message.payloadAsString<br />
method = self.eventContext.getMessage().getProperty('http.method')<br />
self.log.info('processing method = '+method)<br />
nStatus = 200 # OK<br />
if method == 'GET':<br />
self.response = BusinessObject().today()<br />
else:<br />
nStatus = 400 # Bad request<br />
self.response = 'Invalid HTTP method called!'<br />
responseMessage = mule.Default<strong>Mule</strong>Message(self.response)<br />
responseMessage.setIntProperty('http.status', nStatus)<br />
return responseMessage
Portable Business Objects<br />
#!/usr/bin/env jython<br />
#<br />
# Listing 3<br />
#<br />
# Place this file in the module $MULE_HOME/lib/usr/article instead of<br />
# in a .jar if you want to mule punch it.<br />
from datetime import date<br />
class BusinessObject(object):<br />
# *** Public members ***<br />
def today(self): # Return today as a string<br />
return str(date.today())
<strong>Mule</strong> Punching Your Code<br />
• From the Ruby/Python jargon “duck punching”, derived<br />
from duck typing. It means “punch the duck until it gives<br />
you the type you expect.”<br />
• Modify the code at run-time<br />
• In a <strong>Mule</strong>/Spring container we decided to call it “mule<br />
punching” because it’d tell us that we’re modifying code<br />
intended for a Java environment<br />
• You may dynamically add Java, Python, or any other<br />
functionality as long as the container’s class loader can<br />
find the code you’re punching and it’s dependencies
<strong>Mule</strong> Punchint Your Code<br />
<strong>Mule</strong> libraries<br />
Code that can be modified<br />
at runtime<br />
Java libraries<br />
Code that can only be modified<br />
with a re-start<br />
Python libraries<br />
mulescript.py muleservice.py businessmodule.py<br />
service<br />
endpoints<br />
JBoss<br />
Component<br />
<strong>Mule</strong> ESB Services Host and Integration Platform<br />
other<br />
system<br />
Other <strong>Mule</strong><br />
Component<br />
Spring<br />
Component<br />
DB
<strong>Mule</strong> Punching Your Code<br />
import simplejson as json<br />
import org.mule as mule<br />
# Enable dynamic updates to the script:<br />
reload(businessmodule)<br />
class Sample<strong>Mule</strong>Component(object):<br />
.<br />
def serviceRequest(self):<br />
if self.eventContext is not None:<br />
self.payload = self.eventContext.getMessage().getPayloadAsString()<br />
method = self.eventContext.getMessage().getPayloadAsStringroperty('http.method')<br />
self.log.info('processing method = '+method)<br />
nStatus = 200 # OK<br />
if method == 'GET':<br />
self.response = BusinessObject().today()<br />
else:<br />
nStatus = 400 # Bad request<br />
self.response = 'Invalid HTTP method called!'<br />
self.response = json.dumps({ 'nStatus' : nStatus, 'response' : self.response})<br />
responseMessage = mule.Default<strong>Mule</strong>Message(self.response)<br />
responseMessage.setIntProperty('http.status', nStatus)<br />
return responseMessage
<strong>Mule</strong> Punching Your Code<br />
import com.google.gson as gson<br />
.<br />
.<br />
# Enable dynamic updates to the script:<br />
reload(businessmodule)<br />
class Sample<strong>Mule</strong>Component(object):<br />
# *** Class members ***<br />
converter = gson.Gson()<br />
# *** Public members ***<br />
.<br />
def serviceRequest(self):<br />
if self.eventContext is not None:<br />
self.payload = self.eventContext.getMessage().getPayloadAsString()<br />
method = self.eventContext.getMessage().getProperty('http.method')<br />
self.log.info('processing method = '+method)<br />
nStatus = 200 # OK<br />
if method == 'GET':<br />
self.response = BusinessObject().today()<br />
else:<br />
nStatus = 400 # Bad request<br />
self.response = 'Invalid HTTP method called!'<br />
self.response = Sample<strong>Mule</strong>Component.converter.toJson({ 'nStatus' : nStatus,<br />
'response' : self.response, 'encoder' : 'Gson' })<br />
responseMessage = mule.Default<strong>Mule</strong>Message(self.response)<br />
responseMessage.setIntProperty('http.status', nStatus)<br />
return responseMessage
Scripting Results<br />
• Coding time reduced by at least 50%<br />
• Developers are fluent in Java and Python<br />
• Source code reduced by 30% to 75%<br />
• Algorithmic code saw the least reduction<br />
• Regular code + API calls average 50%<br />
• Development/testing cycles reduced from 25% to 50%<br />
• Save/test vs. save/build/package/deploy/stop/start<br />
• Can use with or without OSGi<br />
• Language features help to come up with fresh<br />
approaches to problem solving<br />
Development Speed<br />
Python<br />
Java<br />
C<br />
C<br />
Execution Speed<br />
Java<br />
Python
Deployment Topologies
Application Deployment<br />
Load Balancer<br />
Load Balancer<br />
<strong>Mule</strong> 1 <strong>Mule</strong> 2 <strong>Mule</strong> 3 <strong>Mule</strong> 4<br />
<strong>Mule</strong> 5<br />
Failover<br />
JMS Queuing Active<br />
JMS Queuing Active
Application Deployment<br />
Web Services (SOAP, REST)<br />
Reduce the probability of screw ups: make stateless services<br />
Service<br />
Consumers<br />
event-driven<br />
service calls<br />
Round Robin<br />
Load Balancer<br />
(F5, Cisco, etc.)<br />
<strong>Mule</strong> ESB <strong>Mule</strong> ESB <strong>Mule</strong> ESB <strong>Mule</strong> ESB <strong>Mule</strong> ESB<br />
Resources:<br />
MQ, other web services, other <strong>Mule</strong><br />
instances, anything that can be reached by<br />
an endpoint<br />
* All <strong>Mule</strong> instances have identical configurations<br />
* All service implementations are stateless<br />
* The load balancer should be round robin, non-sticky<br />
* Failed <strong>Mule</strong> instances are automatically taken out of load balancer rotation<br />
* Horizontal scalability and fail-over built-in and supported by the balancer<br />
* NOT for transactional operations within the <strong>Mule</strong> cluster!
Application Deployment<br />
Batch Services (time and event-based transactions)<br />
<strong>Mule</strong> high availability, active/passive configuration with heartbeat monitor and automatic fail-over<br />
Service<br />
Consumers<br />
* Heartbeats can be layer 7 (coded by your team or vendor)<br />
or layer 4 (using routing and ICMP/ARP/TCP)<br />
Load Balancer<br />
(F5, Cisco, etc.)<br />
<strong>Mule</strong> ESB<br />
clustering<br />
component<br />
<strong>Mule</strong> ESB<br />
attached to service and idling - don't wait for fail-over!<br />
Resources:<br />
MQ, other web services, other <strong>Mule</strong><br />
instances, anything that can be reached by<br />
an endpoint<br />
* Use a load balancer instead of Apache or proxy<br />
* Define a heartbeat or other availability monitor<br />
* On primary system failure (solid paths), switch control to secondary<br />
* From the load balancer: switch primary and secondary roles<br />
* Identical configurations for both <strong>Mule</strong> ESBs except for clustering<br />
* Except where not allowed by resource topology, both primary and<br />
secondary attach to the same endpoint in the resource (JMS,<br />
JDBC, HTTP, whatever)<br />
* Assume that if it can be done with vm:, it can be done with cluster:
Application Deployment<br />
This architecture has a lower cost of operation and simplifies power consumption and administration.<br />
Application 1 Application 2<br />
Web Service 1 Web Service 2<br />
JBoss<br />
<strong>Mule</strong> ESB Container<br />
MQ<br />
Java 6<br />
Java 6<br />
Java 6<br />
Linux<br />
Linux<br />
Linux<br />
Virtual Machine<br />
Virtual Machine<br />
Virtual Machine<br />
Multi-Core Intel or AMD Processors<br />
Simplify the architecture by having a common platform for all systems. This platform can be replicated across multiple data<br />
centers.<br />
* Virtual Machine: VMware or Xen hosted on Windows; consider Amazon EC2 as a viable, low-cost alternative<br />
* Linux: Ubuntu Server<br />
* PowerBuilder applications (end-user) migrate to JBoss + Wicket or a similar configuration<br />
* All web services are hosted by <strong>Mule</strong> ESB<br />
* The <strong>Mule</strong> ESB and JBoss servers are separate from one another<br />
* MQ clusters have a similar architecture; JBoss messaging and Websphere MQ<br />
* Java 6 as a minimum
Application Deployment<br />
App and service requests<br />
may come from the open Internet<br />
Each data center will have a cluster of two or more physical systems.<br />
Internet<br />
Each system will virtually host two or more applications/<br />
environments deployed as described in the previous diagram.<br />
The system is designed for horizontal scalability (more traffic, more<br />
virtual or physical servers.<br />
The system has inherent fail-over built in.<br />
App Balancer<br />
Use physical<br />
load balancers;<br />
can be Linux systems<br />
or dedicated F5<br />
balancers - separate from<br />
cluseter<br />
Services<br />
Balancer<br />
MQ<br />
Master<br />
Application<br />
Active<br />
Web Services<br />
Active<br />
Distributed<br />
Cache<br />
MQ<br />
Slave<br />
Application<br />
Active<br />
Web Services<br />
Active<br />
Distributed<br />
Cache<br />
Virtual Host (Intel, AMD)<br />
Virtual Host (Intel, AMD)<br />
Disk<br />
Disk<br />
SAN
Application Deployment<br />
Data Center Europe<br />
Data Center Japan<br />
App Cluster<br />
App Cluster<br />
Internet<br />
App Cluster<br />
App Cluster<br />
Expert<br />
Claims Mgmt<br />
Data Center US<br />
App Cluster<br />
App Cluster<br />
Each data center has an application cluster<br />
The app clusters have identical<br />
configurations; only the app itself may vary<br />
by locale<br />
Designated data center also functions as the<br />
global services processing hub; all<br />
applications talk to this cluster (e.g. Claims<br />
Management) regardless of where the app<br />
calling them is from.<br />
The global services clusters are separate<br />
physically and logically from the application<br />
clusters which may include locale-specific<br />
web services and data stores.<br />
Claims Mgmt<br />
Informix<br />
Legacy System<br />
Legacy System<br />
Legacy System
Wanna know more about real life cloud, scalable systems<br />
Subscribe to the newsletter!<br />
http://eugeneciurana.com/scalablesystems<br />
http://twitter.com/ciurana technology tweets<br />
Questions<br />
Eugene Ciurana<br />
eugenex@mulesoft.com