Developer / Architect @ Ixor
@ddewaele
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
A specialisation of and implementation approach for service-oriented architectures (SOA) used to build flexible, independently deployable software systems.
Wikipedia
A small services with independent lifecycles that work together modelled around a business domain.
Sam Newman
Service A
Service A
Service A
8001
8002
8003
Eureka
Client 1
Lookup service A
@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>Text
@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>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
@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/**@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");
}
}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
config
service A
config
service B
config
service A
config
service B
Filesystem
Filesystem
service B
service A
config server
service-a.yml
service-b.yml
git repo
@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>REST interface
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties@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>service B
service A
config server
service-a.yml
service-b.yml
git repo
bootstrap
yml
bootstrap
yml
service B
service A
config
server
service-a.yml
git repo
service-b.yml
decrypt text
encrypt text
SSH
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