Microservice Architectures — which are the norm in some domains — have recently received lots of attentions in general computing and are becoming the mainstream architectural style to develop distributed systems. As suggested by the name, the main idea behind micro services is to decompose complex applications in, small, autonomous and loosely coupled processes communicating through a language and platform independent API. This architectural style facilitates a modular approach to system-building.
This webcast will (1) introduce the main principles of the Microservice Architecture, (2) showcase how the Global Data Space abstraction provided by Vortex ideally support thee microservices architectural pattern, and (3) walk you through the design and implementation of a micro service application for a real-world use case.
2. Microservice architectures are one of the latest
buzz in software architectures
Let’s try to understand what microservices are and
how to build microservice architectures
5. 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
10. Server Tier
Challenges
Innovation is constrained
by the fact that we cannot
easily mix different
technologies for
implementing the various
functionalities
Same Technology Stack
11. Server Tier
Challenges
Incremental 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
12. Challenges
Loose 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
17. Benefits
Unconstrained Innovation
as we choose the
technologies stack that
makes the most sense for
implementing a given
feature
Server Tier
Process
Functionality
18. 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
Process
Functionality
19. 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
20. Performance of
microservice architectures
may be degraded by the
higher cost of
communication if the right
technology is not used
Server Tier
Challenges
Monolithic
Implementation
Microservice
Implementation
In-Process
Communication
Inter-Process/Host Communication
21. 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
Challenges
Monolithic
Implementation
Microservice
Implementation
25. When a system does not exist
we can use the Bounded
Context as defined in [3]
System Objectives
Microservices
Identifying
Microservices Bounded Context
26. Bounded Context
Domain-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
27. 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
Microservices
bounded context
micro-service canonical
model
system canonical model
28. 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
29. 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
30. 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
31. 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
32. (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
Deployment
Failure Isolation
Highly Observable
Stateless
35. 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
TopicA
QoS
TopicB
QoS
TopicC
QoS
TopicD
QoS
Global Data Space
36. 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
TopicA
QoS
TopicB
QoS
TopicC
QoS
TopicD
QoS
Dynamic Discovery
38. A domain-wide information’s
class A Topic defined by means
of a <name, type, qos>
Topic
DDS Global Data Space
...
Data
Writer
Data
Writer
Data
Writer
Data
Reader
Data
Reader
Data
Reader
Data
Reader
Data
Writer
TopicA
QoS
TopicB
QoS
TopicC
QoS
TopicD
QoS
Topic
Type
Name
QoS
41. 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
42. 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
44. Topic types can be expressed
using different syntaxes,
including IDL and ProtoBuf
Topic Type
class CarDynamics:
constructor:
(@cid, @x, @y, @dx, @dy) ->
CoffeeScript
45. 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#
46. 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
48. 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
TopicA
QoS
TopicB
QoS
TopicC
QoS
TopicD
QoS
QoS - Enabled
49. 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
52. 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: 𝜨∞
=𝜨 ∪ {∞}
53. 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
54. 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
55. Samples can be selected
using composable content
and status predicates
Sample Selectors
DataReader Cache
DataReader
...
56. 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
57. Content Filters
can be used to
project on the
local cache only
the Topic data
satisfying a given
predicate
Content
Filters struct CarDynamics {
@key
string cid;
long x; long y;
float dx; long dy;
}
cid x y dx dy
GR 33N GO 167 240 45 0
LO 00V IN 65 26 65 0
AN 637 OS 32 853 0 50
AB 123 CD 325 235 80 0
“dx > 50 OR dy > 50”
Type
CarDynamics
cid x y dx dy
LO 00V IN 65 26 65 0
AB 123 CD 325 235 80 0
Reader Cache
58. 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
59. Reader Cache
Queries can be
used to select out
of the local cache
the data matching
a given predicate
Queries struct CarDynamics {
@key
string cid;
long x; long y;
float dx; long dy;
}
cid x y dx dy
GR 33N GO 167 240 45 0
LO 00V IN 65 26 65 0
AN 637 OS 32 853 0 50
AB 123 CD 325 235 80 0
“dx > 50 OR dy > 50”
Type
CarDynamics
cid x y dx dy
GR 33N GO 167 240 45 0
LO 00V IN 65 26 65 0
AN 637 OS 32 853 0 50
AB 123 CD 325 235 80 0
cid x y dx dy
LO 00V IN 65 26 65 0
AB 123 CD 325 235 80 0
query
60. 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
61. Selector Example
// == ISO C++ DDS API ==
auto data =
dr.select()
.content(query)
.state(data_state)
.instance(handle)
.read();
64. CopyrightPrismTech,2015
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;
}
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
65. CopyrightPrismTech,2015
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;
}
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
66. CopyrightPrismTech,2014
Writing Data in Scala
import 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)
}
}
}
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
67. CopyrightPrismTech,2014
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)
}
}
}
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
68. CopyrightPrismTech,2015
Writing Data in Python
import dds
import time
if __name__ == '__main__':
topic = dds.Topic("SmartMeter", "Meter")
dw = dds.Writer(topic)
while True:
m = readMeter()
dw.write(m)
time.sleep(0.1)
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
69. CopyrightPrismTech,2015
Reading Data in Python
import dds
import 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
enum UtilityKind {
ELECTRICITY,
GAS,
WATER
};
struct Meter {
string sn;
UtilityKind utility;
float reading;
float error;
};
#pragma keylist Meter sn
71. 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
infrastructuresdk
73. 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 context
bounded context
micro-service Vortex Data Model
system canonical Vortex
Data model
77. 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
TopicA
QoS
TopicB
QoS
TopicC
QoS
TopicD
QoS
TopicD
QoS
TopicD
QoS
TopicA
QoS
79. 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
88. 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
infrastructuresdk
89. 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
infrastructuresdk
90. 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
infrastructuresdk
93. Timeout
As 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;
}
96. Microservices architectures bring
several architectural benefits
Vortex ensures that the operational and
performance cost of adopting micro
services architectures if minimised
In
Summary
97. [1] S. Newman. Building Microservices.
[2] M. Fowler, J. Lewis. Microservices
[3] E. Evans, Domain-Driven Design