Date post: | 08-Jan-2017 |
Category: |
Technology |
Upload: | prismtech |
View: | 866 times |
Download: | 2 times |
Microservice Architectures
AngeloCorsaro,PhDChiefTechnologyOfficer
with
Part-I
Microservice architectures are on of the latest buzz in software architectures
Let’s try to understand what microservices are and how to build microservice architectures
microserviceS “Microservices are small, autonomous services that work together.” [1]
microservice Architectural
style
“The microservice architectural style is an approach to developing a single
application as a suite of small services, each running in its own
process and communicating with lightweight mechanisms.” [2]
Monolith vs.
microservice
A good way of getting the gist of the microservice architectural style is to
compare it to the more traditional monolithic approach
Monolithic Architectures
Monolithic Architectures
Traditional 3 -Tier architectures with
decomposition based on Technology / Skills
boundaries and modularisation based on
libraries
Client Tier (UI)
Server Tier
Data Tier
Monolithic Architectures
A monolithic applications merges multiple
functionalities in the same executable
Server Tier
Process
Functionality
ChallengesScaling monolithic
applications is challenging as we have just one degree
of freedom to scale out
The same challenge applies to replication
Server Tier
Load Balancer
Server Tier
ChallengesInnovation is constrained by the fact that we cannot
easily mix different technologies for
implementing the various functionalities
Same Technology Stack
Server Tier
ChallengesIncremental Change is
constrained by the fact that can’t incrementally
deploy new functionalities . We need
to redeploy an entire subsystem. Hard to hide internal
details and limit dependencies
ChallengesLoose Coupling and High
Cohesion are harder to achieve and especially to
preserve as the “barriers” between functionalities are
very thin
Server Tier
Module / Library Boundaries
Microservice Architectures
Server Tier
ProcessFunctionality
Microservice ArchitecturesIndividual functionalities
become unit of deployment and run in
their own process
Microservice Architectures
Microservices communicate through
some lightweight mechanism
Server Tier
ProcessFunctionality
Server Tier
BenefitsScaling microservice
applications is easier as we can scale out individual
functionalities
BenefitsUnconstrained Innovation
as we choose the technologies stack that
makes the most sense for implementing a given
feature
Server Tier
ProcessFunctionality
Incremental Change is facilitated allowing
incremental deployment of new functionalities.
Potentially different version of the same micro service could be running at the same time!
Benefits Server Tier
ProcessFunctionality
Loose Coupling and High Cohesion are easier to
achieved to preserve as the “barriers” between functionalities are very
thick
Server Tier
Process Boundary / Share Nothing
Benefits
Performance of microservice architectures
may be degraded by the higher cost of
communication if the right technology is not used
Server Tier
ChallengesMonolithic
Implementation
Microservice Implementation
In-Process Communication
Inter-Process/Host Communication
Deployment and Operation of systems
based on the microservice architectures is inherently more complex, especially
at scale and when the right technologies are not used
Server Tier
ChallengesMonolithic
Implementation
Microservice Implementation
Designing Microservice Architectures
Identifying Microservices
Microservices are supposed to capture business and not
technical features of a system
Microservices
Identifying Microservices
When a monolithic systems is already existing, micro
services can be created by separating the various
features
Microservices
When a system does not exist we can use the Bounded Context as defined in [3]
System Objectives
Microservices
Identifying Microservices Bounded Context
Bounded ContextDomain-Driven Design (DDD) divides a complex domain into a series of
Bounded Context. Where a context means a specific system responsibility, and a bounded context means that responsibility is
enforced with explicit boundaries.
Each bounded context has its own canonical model and communication between bounded context happens through a system-
canonic al model
Microservices are ideally mapped to Bounded Context.
Each Bounded context has potentially its own canonical model
Communication between Bounded Context uses the system-wide
canonical model
Microservicesbounded context
micro-service canonical model
system canonical model
A consequence of applying the Bounded Context technique is
that data management in micro services architectures is
decentralised
Decentralised Data Management
bounded context
micro-service canonical model
system canonical model
Every microservice owns and manages its data without relying
on a shared data-base.
Consequently microservice architectures are build under
eventual consistency assumptions
Decentralised Data Management
bounded context
micro-service canonical model
system canonical model
Any organisation that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.
— M. Conway, 1967
Conway’s Law
Conway’s tells us that to be successful in applying
microservice architectures we should have cross-functional
teams organised around business capabilities
Conway’s LAW Implications
image curtesy of M. Fowler http://martinfowler.com/articles/microservices.html
(This is an adaptation of a Figure from [1])
Microservices small autonomous
services
Modelled around business concepts
Highly Automated
Hide internal implementation
details
Decentralised
Independent DeploymentFailure Isolation
Highly Observable
Vortex Overview
Vortex's Coordination Model
Applications can autonomously and asynchronously read and
write data enjoying spatial and temporal decoupling
DDS Global Data Space
...
Data Writer
Data Writer
Data Writer
Data Reader
Data Reader
Data Reader
Data Reader
Data Writer
TopicAQoS
TopicBQoS
TopicCQoS
TopicDQoS
Global Data Space
Built-in dynamic discovery isolates applications from
network topology and connectivity details
DDS Global Data Space
...
Data Writer
Data Writer
Data Writer
Data Reader
Data Reader
Data Reader
Data Reader
Data Writer
TopicAQoS
TopicBQoS
TopicCQoS
TopicDQoS
Dynamic Discovery
Topic
A domain-wide information’s class A Topic defined by means
of a <name, type, qos>
TopicDDS Global Data Space
...
Data Writer
Data Writer
Data Writer
Data Reader
Data Reader
Data Reader
Data Reader
Data Writer
TopicAQoS
TopicBQoS
TopicCQoS
TopicDQoS
TopicTypeName
QoS
Topic Types
Topic Types: Language Independent
Definitions
Topic types can be expressed using different syntaxes,
including IDL and ProtoBuf
Topic Type struct CarDynamics { string cid; long x; long y; float dx; long dy; } #pragma keylist CarDynamics cid
IDL
Topic types can be expressed using different syntaxes,
including IDL and ProtoBuf
Topic Type message CarDynamics { option (.omg.dds.type) = {name: "CarDynamics"}; required string cid = 0 [(.omg.dds.member).key = true]; required long x = 1; required long y = 2; required float dx = 3; required long dy = 4; }
ProtoBuf
Topic Types: Language Specific
Definitions
Topic types can be expressed using different syntaxes,
including IDL and ProtoBuf
Topic Type class CarDynamics: constructor: (@cid, @x, @y, @dx, @dy) ->
CoffeeScript
Topic types can be expressed using different syntaxes,
including IDL and ProtoBuf
Topic Type public struct CaDynamics { public string cid { get; set; } public int x { get; set; } public int y { get; set; } public int dx { get; set; } public int dy { get; set; } public CaDynamics (string cid, int x, int y, int dx, int dy) { this.cid = cid; this.x = x; this.y = y; this.dx = dx; this.dy = dy; } }
C#
Topic types can be expressed using different syntaxes,
including IDL and ProtoBuf
Topic Type @KeyList ( topicType = "CarDynamics", keys = {"cid"})public class CarDynamics { public String cid; public int x; public int dx; public int y; public int dy; public CarDynamics(String s, int a, int b, int c,int d) { this.cid = s; this.x = a; this.dx = b; this.y = c; this.dy = d; } @Override public String toString() { … }}
Java
TopicAQoS
TopicCQoS ...
TopicBQoS
TopicDQoS
PartitionsThe Global Data Space can be
divided in to arbitrary partitions
The source and destination of data is identified by means of “Partition/Topic” expressions
“Red”
“Blue”
QoS policies allow to express temporal and availability
constraints for data
DDS Global Data Space
...
Data Writer
Data Writer
Data Writer
Data Reader
Data Reader
Data Reader
Data Reader
Data Writer
TopicAQoS
TopicBQoS
TopicCQoS
TopicDQoS
QoS - Enabled
A collection of policies that control non-
functional properties such as reliability,
persistence, temporal constraints and priority
QoS
HISTORY
LIFESPAN
DURABILITY
DEADLINE
LATENCY BUDGET
TRANSPORT PRIO
TIME-BASED FILTER
RESOURCE LIMITS
USER DATA
TOPIC DATA
GROUP DATA
OWENERSHIP
OWN. STRENGTH
LIVELINESS
ENTITY FACTORY
DW LIFECYCLE
DR LIFECYCLE
PRESENTATION
RELIABILITY
PARTITION
DEST. ORDER
RxO QoS Local QoS
QoS Policies controlling end-to-end properties
follow a Request vs. Offered
QoS Domain
Participant
DURABILITY
OWENERSHIP
DEADLINE
LATENCY BUDGET
LIVELINESS
RELIABILITY
DEST. ORDER
Publisher
DataWriter
PARTITION
DataReader
Subscriber
DomainParticipant
offered QoS
Topicwrites reads
Domain Idjoins joins
produces-in consumes-from
RxO QoS Policies
requested QoS
Interacting with the Data Cache
Each Data Reader is associated with a Cache
The Cache stores the last n∊𝜨∞ samples for each
relevant instance
Data Cache
DataReader Cache
DataReader
...
Samples
Instances
Cache
Where: 𝜨∞=𝜨 ∪ {∞}
The action of reading samples for a Reader Cache
is non-destructive.
Samples are not removed from the cache
Reading Data
DataReader Cache
DataReader
...
DataReader Cache
DataReader
...read
The action of taking samples for a Reader Cache
is destructive.
Samples are removed from the cache
Taking Data
DataReader Cache
DataReader
...
DataReader Cache
DataReader
...take
Samples can be selected using composable content
and status predicates
Sample Selectors
DataReader Cache
DataReader
...
Filters allow to control what gets into a DataReader
cache
Filters are expressed as SQL where clauses or as
Java/C/JavaScript predicates
Content-Filtering
DataReader Cache
DataReader
...
Filter
Application
Network
Content Filters can be used to project on the
local cache only the Topic data
satisfying a given predicate
Content Filters structCarDynamics{
@keystringcid;longx;longy;floatdx;longdy;}
cid x y dx dyGR 33N GO 167 240 45 0LO 00V IN 65 26 65 0AN 637 OS 32 853 0 50AB 123 CD 325 235 80 0
“dx>50ORdy>50”
Type
CarDynamics
cid x y dx dyLO 00V IN 65 26 65 0AB 123 CD 325 235 80 0
Reader Cache
Queries allow to control what gets out of a
DataReader Cache
Queries are expressed as SQL where clauses or as
Java/C/JavaScript predicates
Content-Based Selection
DataReader Cache
DataReader
...
Query
DataReader Cache
DataReader
...
Application
Network
Reader Cache
Queries can be used to select out of the local cache
the data matching a given predicate
QueriesstructCarDynamics{@keystringcid;longx;longy;floatdx;longdy;}
cid x y dx dyGR 33N GO 167 240 45 0LO 00V IN 65 26 65 0AN 637 OS 32 853 0 50AB 123 CD 325 235 80 0
“dx>50ORdy>50”
Type
CarDynamics
cid x y dx dyGR 33N GO 167 240 45 0LO 00V IN 65 26 65 0AN 637 OS 32 853 0 50AB 123 CD 325 235 80 0
cid x y dx dyLO 00V IN 65 26 65 0AB 123 CD 325 235 80 0
query
State based selection allows to control what gets out of a DataReader Cache
State base selectors predicate on samples meta-
information
State-Based Selection
DataReader Cache
DataReader
...
State Selector
DataReader Cache
DataReader
...
Application
Network
Selector Example
// == ISO C++ DDS API ==
auto data = dr.select() .content(query) .state(data_state) .instance(handle) .read();
your first vortex app
Cop
yrig
ht P
rism
Tech
, 201
4
Anatomy of a DDS Application
Cop
yrig
ht P
rism
Tech
, 201
5
Writing Data in C++#include <dds.hpp>
int main(int, char**) {
DomainParticipant dp(0); Topic<Meter> topic(“SmartMeter”); Publisher pub(dp); DataWriter<Meter> dw(pub, topic);
while (!done) { auto value = readMeter() dw.write(value); std::this_thread::sleep_for(SAMPLING_PERIOD); }
return 0; }
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Cop
yrig
ht P
rism
Tech
, 201
5
Reading Data in C++#include <dds.hpp>
int main(int, char**) {
DomainParticipant dp(0); Topic<Meter> topic(”SmartMeter”); Subscriber sub(dp); DataReader<Meter> dr(dp, topic);
LambdaDataReaderListener<DataReader<Meter>> lst; lst.data_available = [](DataReader<Meter>& dr) { auto samples = data.read(); std::for_each(samples.begin(), samples.end(), [](Sample<Meter>& sample) { std::cout << sample.data() << std::endl; } } dr.listener(lst); // Print incoming data up to when the user does a Ctrl-C std::this_thread::join(); return 0; }
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Cop
yrig
ht P
rism
Tech
, 201
4
Writing Data in Scalaimport dds._import dds.prelude._import dds.config.DefaultEntities._
object SmartMeter { def main(args: Array[String]): Unit = { val topic = Topic[Meter](“SmartMeter”) val dw = DataWriter[Meter](topic) while (!done) { val meter = readMeter() dw.write(meter) Thread.sleep(SAMPLING_PERIOD) } }}
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Cop
yrig
ht P
rism
Tech
, 201
4
Reading Data in Scala
import dds._import dds.prelude._import dds.config.DefaultEntities._
object SmartMeterLog { def main(args: Array[String]): Unit = { val topic = Topic[Meter](“SmartMeter”) val dr = DataReader[Meter](topic) dr listen { case DataAvailable(_) => dr.read.foreach(println) } }}
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Cop
yrig
ht P
rism
Tech
, 201
5
Writing Data in Python
import dds import timeif __name__ == '__main__': topic = dds.Topic("SmartMeter", "Meter") dw = dds.Writer(topic) while True: m = readMeter() dw.write(m) time.sleep(0.1)
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Cop
yrig
ht P
rism
Tech
, 201
5
Reading Data in Pythonimport ddsimport sys def readData(dr): samples = dds.range(dr.read()) for s in samples: sys.stdout.write(str(s.getData())) if __name__ == '__main__': t = dds.Topic("SmartMeter", "Meter") dr = dds.Reader(t) dr.onDataAvailable = readData
enumUtilityKind{ ELECTRICITY, GAS, WATER};structMeter{ stringsn; UtilityKindutility; floatreading; floaterror;};#pragmakeylistMetersn
Vortex Technology Stack
Device implementations optimised for OT, IT and
consumer platforms
Native support for Cloud and Fog Computing Architectures
Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Vortex-Based Microservices
Microservices are ideally mapped to Bounded Context.
Each Bounded context has potentially its own canonical model
Communication between Bounded Context uses the system-wide
canonical model
Bounded contextbounded context
micro-service Vortex Data Model
system canonical Vortex Data model
micro-service partition
system partition
micro-service data model
system (inter-svc) data model
Benefits
Decentralised Infrastructure
The relevant portion of the data space is projected on the
application address space. Each typed projection is commonly called
a Cache
No single point of failure or bottleneck
No central server to configure/ manage
Decentralised Data Space
Data Writer
Data Writer
Data Writer
Data Reader
Data Reader
Data Reader
Data Writer
TopicAQoS
TopicBQoS
TopicCQoS
TopicDQoS
TopicDQoS
TopicDQoS
TopicAQoS
Persistence
Vortex provides a high performance distributed
durability service that can be used to achieve different level
of temporal decoupling
Durability Services take ownership for “Partition/Topic “
expressions
Distributed Durability
Performance
High Performance 30 μs peer-to-peer latency
7 μs inter-core latency
4+ Mmsgs/sec p2p throughput
Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
>10 μs fog/cloud routing latency
High Performance Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Deployment Fexibility
Microservice deployment
The common guideline for Microservices is to deploy
them across different hosts to limit the impact of a
failing machine
Microservice deployment
The one micro-service per host rule can be
constraining in terms of performance
Microservice deployment
Vortex location transparency and intra-host
communication optimisation allow to exploit the benefits
of micro-service architectures without major
performance costsUltra-Low Latency
Inter-Process Comm
Technology Agnostic
Vortex is a Polyglot and Interoperable across
Programming Languages Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Fully Independent of the Cloud Infrastructure
Private Clouds
Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Native Integration with the hottest real-time analytics
platforms and CEP Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Integration with mainstream Dashboard Technologies
Device-2-DeviceDevice-2-Cloud
Fog-2-Cloud
Device-2-Fog
Cloud-2-Cloud
Fog-2-Fog
infra
stru
ctur
esd
k
Native Support for Microservices
Patterns
TimeoutAs a general rule Vortex APIs
are non-blocking
Blocking API calls are all equipped with timeout
#include <dds.hpp>
int main(int, char**) {
DomainParticipant dp(0); Topic<Meter> topic(“SmartMeter”); Publisher pub(dp); DataWriter<Meter> dw(pub, topic);
while (!done) { auto value = readMeter() dw.write(value); std::this_thread::sleep_for(SAMPLING_PERIOD); }
return 0; }
Worker PatternVortex provides several ways of supporting the
worker pattern
CIRCUIT BREAKERVortex communications primitive implement the
circuit breaker pattern thus reducing the complexity of
adopting it
Microservices architectures bring several architectural benefits
Vortex ensures that the operational and performance cost of adopting micro services architectures if minimised
In Summary
[1] S. Newman. Building Microservices. [2] M. Fowler, J. Lewis. Microservices [3] E. Evans, Domain-Driven Design
Cop
yrig
ht P
rism
Tech
, 201
5