Spring Cloud-based Microservices, the Netflix Architecture

Who am I ?
Davy De Waele
Developer / Architect @ Ixor
@ddewaele



Outline
- What are micro-services and why should you care ?
- What is Spring Cloud / Netflix OSS
- Spring Cloud patterns
- Service Discovery (Eureka)
- Client Side Load Balancing (Ribbon)
- Intelligent Routing (Zuul)
- Centralized Configuration (Config)
- Circuit Breaker (Hystrix)
- What about security / monitoring / ... ?

What are microservices ?
Independently deployable, small, modular services in which each service runs a unique process and communicates through a well-defined, lightweight mechanism to serve a business goal.
Martin Fowler

What are microservices ?
A specialisation of and implementation approach for service-oriented architectures (SOA) used to build flexible, independently deployable software systems.
Wikipedia

What are microservices ?
A small services with independent lifecycles that work together modelled around a business domain.
Sam Newman

What are microservices ?
- No standard definition
- Subset of SOA
- Nothing to do with ESB
- Opposite of an architecture consisting of monoliths

Monoliths vs Micro-services


Characteristics

- Independent / Autonomous processes
- API driven
- Independent deployments
- Focussed on 1 task / business domain
- Design for failure
Costs associated
-
Tooling
- Automatic deployments
- Continuous delivery
- Service monitoring
-
Architecture complexity
- API driven
- Eventual Consistency
- Asynchronous behaviour
- Lots of decoupling


What is Spring Cloud ?
- Spring Cloud integrates Netflix OSS with the Spring Ecosystem using auto-configuration



What is Spring Cloud
- Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
- Service Discovery: an embedded Eureka server can be created with declarative Java configuration

What is Spring Cloud
- Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
- Client Side Load Balancer: Ribbon

What is Spring Cloud
- External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
- Router and Filter: automatic regsitration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation

What is Spring (boot) ?
- Spring is a de-facto standard application framework for java
- Spring Boot is the icing on the Spring cake.
- It represents an opinionated view of building production-ready Spring applications.


What is Netflix OSS
- Open source infrastructure components for distributed architectures
- give it away give it away give it away now....


Service Discovery : Eureka
- What ?
- Service to help you locate other services
- Mid-tier load balancing (not proxy based)
- REST based service / java based client
- Contains a client and a server

Service Discovery : Eureka

Service A
Service A
Service A
8001
8002
8003
Eureka
Client 1
Lookup service A
Service Discovery : Eureka
-
Why ?
- Services can come and go
- Location transparancy (no hostnames / ip adresses)
- Avoid error prone configs

Eureka Server
- Set of REST endpoints
- User Interface
- Allows services to register themselves
- Provides an address book to your clients

Eureka Server

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
public static void main(String[] args) {
SpringApplication.run(EurekaServer.class, args);
}
}server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

Eureka Client
- Enable Eureka discovery configuration with an annotation
- Turns on discovery and let the autoconfiguration find the eureka classes
- Provides meta data about itself to Eureka (host / port / instanceId)
- Heartbeat mechanism
- Eureka client registers itself (the server) but also allows it to query other services.

Eureka Client
Text



Eureka Client
@SpringBootApplication
@EnableEurekaClient
public class RegisteredService1 {
public static void main(String[] args) {
SpringApplication.run(RegisteredService1.class, args);
}
}spring:
application:
name: registered-service1
server:
port: 0
eureka:
instance:
instanceId: ${spring.application.name}:
${vcap.application.instance_id:${spring.application.instance_id:
${random.value}}}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>Zuul
- Zuul is the front door for all requests from devices and web sites to your backends
- It acts as a gateway / reverse proxy
- Sits on the edge of your architecture


Service A
Service B
Service C
8001
8101
8201
/service-b
UI
REST calls
/service-a
/service-c
8002
8003
8102
8103
8202
8203
Solves
CORS
Zuul

Zuul Proxy
@SpringBootApplication
@EnableZuulProxy
public class ZuulProxy {
public static void main(String[] args) {
SpringApplication.run(ZuulProxy.class, args);
}
}zuul:
routes:
simpleservice1:
path: /simpleservice1/**
url: http://localhost:9001/data1
simpleservice2:
path: /simpleservice2/**
url: http://localhost:9002/data2<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>zuul:
routes:
registered-service1: /registered-service1/**
registered-service2: /registered-service2/**
Zuul Proxy
@SpringBootApplication
@EnableZuulProxy
public class ZuulProxy extends WebSecurityConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(ZuulProxy.class, args);
}
public void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/routes/**").permitAll()
.antMatchers("/simpleservice1/**").hasRole("USER")
.antMatchers("/simpleservice2/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
@Autowired
protected void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("ADMIN", "USER").and()
.withUser("manager").password("password").roles("MANAGER","USER").and()
.withUser("guest").password("password").roles("GUEST");
}
}Zuul

Service A
Service B
Service C
8001
8101
8201
/service-b
UI
REST calls
/service-a
/service-c
Spring Security
ROLE_ADMIN
ROLE_USER
ROLE_OPERATOR
fine-grained
ACL
coarse-grained
ACL
Spring Cloud Configuration
- Centralized config for your micro-services
- Based on a git repository (other backend implementations possible)
- Consists of a Server and a Client part
- Lots of security options (securing both the configuration server as well as the git repo)
- Supports encrypting / decrypting values
- Uses standard Spring profile mechanism.
- Push notifications (@RefreshScope)

Spring Cloud Configuration

config
service A
config
service B
config
service A
config
service B
Filesystem
Filesystem
Spring Cloud Configuration

service B
service A
config server
service-a.yml
service-b.yml
git repo

Spring Config Server
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}spring:
cloud:
config:
server:
git:
uri: https://github.com/ddewaele/spring-cloud-config-repo
basedir: target/config # avoid /tmp getting wiped out containing the cloned repo.
cloneOnStart: true
encrypt:
key: mysecret<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>Spring Config Server
REST interface

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
Spring Config Client
@SpringBootApplication
public class ConfigClient {
public static void main(String[] args) {
SpringApplication.run(ConfigClient.class, args);
}
}spring:
application:
name: configclient1
cloud:
config:
uri: http://localhost:8888
label: master
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>Spring Config Client

service B
service A
config server
service-a.yml
service-b.yml
git repo
bootstrap
yml
bootstrap
yml

Spring Config Security

service B
service A
config
server
service-a.yml
git repo
service-b.yml
decrypt text
encrypt text
SSH
Encrypting / Decrypting
Encrypt

curl localhost:8888/decrypt -d "eadaa4e2e765f2ebff88093d6b..."
super strong passwordDecrypt
curl localhost:8888/encrypt -d "super strong password"
eadaa4e2e765f2ebff88093d6b6dec1bbf885e7f90d64e4b09efdconfig:
value: 'a service1-specific config value'
super-secret-value: '{cipher}eadaa4e2e765f2...'
Store
Advanced Security
- Oauth 2
- Zuul integration
- Oauth 2 resources



Monitoring
- Why ?
- Know when things go wrong
- Debug existing issues
- Spot trends
- Alert people / services

Monitoring
- How ?
- Supporting different technologies (java / node / python / ....)
- Avoid Pager Fatigue.
- Allow the developers to control their instrumentation
- Enable service discovery (auto-register services into the monitoring platform)
- No emails !!! DOES NOT WORK.

Monitoring


Monitoring


Monitoring


Monitoring


Monitoring


Thank you

Spring Cloud
By Davy De Waele
Spring Cloud
- 1,121