Microservices in Java: "Using Hazelcast With Microservices"
Microservices in Java: "Using Hazelcast With Microservices"
Microservices in Java: "Using Hazelcast With Microservices"
CONTENTS
234
Survival Is Not Mandatory
500 Easy Steps to Production
You Cant Fix What You Cant Measure
Centralized Configuration
Microservices in Java
BY J O S H LO N G
@RestController
class FulfillmentRestController {
@Autowired
private CounterService counterService;
@RequestMapping(/customers/{customerId}/fulfillment)
Fulfillment fulfill(@PathVariable long customerId) {
// ..
counterService.increment(
meter.customers-fulfilled);
// ..
}
MICROSERVICES IN JAVA
Using Hazelcast
with Microservices
@SpringBootApplication
public class DemoApplication {
www.hazelcast.com/microservices
D Z O NE, INC.
DZ O NE.C O M
3
THE CONFIG CLIENT
# application.properties
spring.cloud.config.uri=http://localhost:8888
spring.application.name=message-client
# will read https://github.com/joshlong/my-config/messageclient.properties
@SpringBootApplication
public class ConfigClientApplication {
CENTRALIZED CONFIGURATION
The Twelve-Factor App methodology provides a set of guidelines
for building applications with good, clean cloud hygiene. One tenet
is that environment-specific configuration should live external to
the application itself. It might live in environment variables, -D
arguments, externalized .properties, .yml files, or any other
place, so long as the application code itself need not be recompiled.
DropWizard, Spring Boot, Apache Commons Configuration, and
others support this foundational requirement. However, this
approach fails a few key use cases: how do you change configuration
centrally and propagate those changes? How do you support
symmetric encryption and decryption of things like connection
credentials? How do you support feature flags which toggle
configuration values at runtime, without restarting the process?
@RequestMapping(/message)
String read() {
return this.message;
}
@EnableConfigServer
@SpringBootApplication
public class ConfigServiceApplication {
MICROSERVICES IN JAVA
@Autowired
public void enumerateServiceInstances(
DiscoveryClient client) {
client.getInstances(reservation-service)
.forEach( si -> System.out.println( si.getHost()
+ : + si.getPort() ));
}
D Z O NE, INC .
DZ O NE .C O M
@EnableDiscoveryClient
@SpringBootApplication
public class ReservationClientApplication {
@EnableZuulProxy
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class EdgeServiceApplication {
@Bean
@LoadBalanced
// lets us use service registry service IDs as hosts
RestTemplate restTemplate() {
return new RestTemplate();
}
MICROSERVICES IN JAVA
@RestController
class TradesStreamingApiGateway {
@Autowired
private MarketService marketService;
@RestController
class ApiClientRestController {
@RequestMethod(method=HttpMethod.GET,
value = /market/trades)
public SseEmitter trades() {
SseEmitter sseEmitter = new SseEmitter();
Observable<StockTrade> trades =
marketService.observeTrades(); // RxJava
trades.subscribe( value -> publishNewTrade(sseEmitter,
value),
sseEmitter::completeWithError,
sseEmitter::complete
);
return sseEmitter;
}
@Autowired
private RestTemplate restTemplate;
@RequestMapping(method = RequestMethod.GET,
value = /reservations/names)
public Collection<String> names() {
ResponseEntity<JsonNode> responseEntity =
restTemplate.exchange(
http://reservation-service/reservations,
HttpMethod.GET, null, JsonNode.class);
// ...
D Z O NE, INC .
CLUSTERING PRIMITIVES
In a complex distributed system, there are many actors with many
roles to play. Cluster coordination and cluster consensus is one of
the most difficult problems to solve. How do you handle leadership
election, active/passive handoff, or global locks? Thankfully, many
technologies provide the primitives required to support this sort of
coordination, including Apache Zookeeper, Redis, and Hazelcast.
Spring Cloud's Cluster support provides a clean integration with all
of these technologies.
DZ O NE .C O M
MICROSERVICES IN JAVA
@RestController
@RequestMapping(/products)
class ProductsApiGatewayRestController {
@Autowired
private MessageChannel products;
@Component
class LeadershipApplicationListener {
@EventListener
public void leadershipGranted(OnGrantedEvent evt) {
// ..
}
@EventListener
public void leadershipRevoked(OnRevokedEvent evt) {
// ..
}
@EnableBinding(Sink.class)
public class ProductHandler {
@Autowired
private ProductRepository products;
@StreamListener(Sink.INPUT)
public void handle(Product p) {
products.addProduct(vote);
}
CIRCUIT BREAKERS
Circuit breakers, like Netflix's Hystrix or JRugged, help prevent
a downstream service from being overwhelmed and help isolate
failures, permitting downstream services time to recover. Systems
are complex, living things. Failure in one system can trigger a
domino effect across other systems if care isn't taken to isolate them.
A circuit breaker will slowly attempt to reintroduce traffic. Circuit
breakers represent connections between services in a system; it is
important to monitor them. Hystrix provides a dashboard for its
circuits. WildFly Swarm has support for using Hystrix. The Play
Framework provides support for circuit breakers. Spring Cloud
also has deep support for Hystrix and the dashboard, as well as
multiplexing the server-sent event streams emitted from different
components into a single stream using Spring Cloud Turbine.
@RestController
class EdgeService {
public Collection<String> fallback(){
// ..
}
@EnableBinding(CrmChannels.class)
@SpringBootApplication
public class ProductsEdgeService {
@RequestMapping(method = RequestMethod.POST)
public void write(@RequestBody Product p) {
Message<Product> msg = MessageBuilder
.withPayload (p).build();
products.send(msg);
}
interface CrmChannels {
@Output
MessageChannel orders();
DISTRIBUTED TRACING
@Output
MessageChannel customers();
It is difficult to reason about a microservice system with RESTbased, messaging-based, and proxy-based egress and ingress points.
How do you trace (correlate) requests across a series of services and
understand where something has failed? This is difficult enough
a challenge without a sufficient upfront investment in a tracing
@Output
MessageChannel products();
D Z O NE, INC .
DZ O NE .C O M
6
strategy. Google introduced their distributed tracing strategy
in their Dapper paper. Apache HTRace is a Dapper-inspired
alternative. Twitter's Zipkin is another Dapper-inspired tracing
system. It provides the trace collection infrastructure and a UI in
which you can view waterfall graphs of calls across services along
with their timings and trace-specific information. Spring Cloud
Sleuth provides an abstraction around the concepts of distributed
tracing. Spring Cloud Sleuth automatically traces common ingress
and egress points in the system. Spring Cloud Zipkin integrates
Twitter Zipkin in terms of the Spring Cloud Sleuth abstraction.
MICROSERVICES IN JAVA
JOIN NOW
DZONE, INC.
150 PRESTON EXECUTIVE DR.
CARY, NC 27513
DZone communities deliver over 6 million pages each month to more than 3.3 million software
888.678.0399
developers, architects and decision makers. DZone offers something for everyone, including
919.678.0300
news, tutorials, cheat sheets, research guides, feature articles, source code and more.
SPONSORSHIP OPPORTUNITIES
sales@dzone.com