2. About Me
Juven has 10 years' experience on software development.
He's currently leading a team in AliExpress, focusing on
improve technical productivity and stability using methods
like Microservices and DevOps.
He authored a book about
Apache Maven.
Twitter: @juvenxu
3. A subsidiary of Alibaba Group.
The largest cross border trading platform in the world.
In 2016 11.11 shopping festival, from 230 countries,
over 6 millions consumers placed 35.78 millions of orders.
5. Back in 2013 …
release queue
dependency hell
unable to start locally
we had only a dozen of applications but more than one hundred of
developers, so developers have to create a branch, and merge it
before releasing, and usually have to wait for other people, who is
releasing the same application.
Too many logics were put into one application, including a lot of very
old java libraries, it’s very easy to have dependency collisions (log is
gone, runtime issue etc.) It’s quite common to see an developer
spend half day resolving a dependency collision issue.
Applications are usually quite complex, running on a customized
version of JBoss, needs a few shell scripts to configure and start, it
usually takes more than 10 minutes. It’s almost impossible to
developers to start his application on his laptop.
6. Back in 2013 …
svn
maven 2
java 6
JBoss 4
war
SpringFramework 2.x
Servlet API 2.x
7. Now
Git & Gitlab
Maven 3
Java 8
Embedded Tomcat 8
jar
Spring Boot &
Spring Cloud
SpringFramework 4.x
Servlet API 3.1
svn
maven 2
java 6
JBoss 4
war
SpringFramework 2.x
Servlet API 2.x
8. The Big Picture
DB HBase NoSql
Tair
Service
Service Service Service
Service Service
Web App Web App Web App
H
S
F
M
Q
DB HBase NoSql
Tair
Service
Service Service Service
Service Service
Web App Web App Web App
H
S
F
M
Q
9. The Big Picture
• AliExpress has hundreds of applications
most of which are Java applications.
• Mainly communicated in sync way using HSF
(similar to gRPC)
• Some communicated in async way using MetaQ
(similar to Kafka)
• Multiple data centers.
• All apps use the same release system and monitoring
system.
10. PrinciplesB
1. Be able to start locally
2. API first
3. Embrace OSS
4. Developers take full responsibility
12. Principle 1: Be Able To Start Locally
• Feedback time: 10+ mins -> 3- mins
• Much easier to understand
• Much easier to debug
The developers heavily rely on our testing environment to deploy their
application and do some simple testing. Even for one single line of
code! and sometimes the testing environment is not stable enough.
To be able to start up locally, we use SpringBoot, and did a lot of
technical debt clean up.
* no more jboss
* no magic scripts etc.
13. Principle 2: API First
• The cost of an incompatible change
to your API is very high!
• In Java world, don’t pollute your
users with unnecessary
dependencies.
because we are almost 100% Java based, so people publish their
API as client.jar, it’s so easy to put logics into the client.jar, and it
quickly become very very fat
1. too much logic in the fat jar
2. Too many transitive dependence in the fat jar
image you depends on 10 services, they each give you a fat jar, each
fat jar has 40 transitive dependencies…. it’s a nightmare
14. Principle 3: Embrace OSS
Microservices
SpringBoot
• Choose the mainstream OSS tools/frameworks, so
• More documents/books
• The developers have more passion to learn
• Can be Googled for problems.
Our R&D teams are getting more and more international, we have
developers don’t know Chinese at all. So asking them to learn Alibaba
frameworks (usually only has Chinese documents, even comments are
Chinese) is almost impossible.
15. Principle 4: Developers
Take Full Responsibility
• Developers are the owner of the applications.
• Responsible to the features, reliability and
performance etc.
• This principle is the core of our DevOps
culture.
• Comprehensive infrastructure is required
• must be simple to use
this is the only scalable way, we have
hundreds of applications but only a few
ops guys.
the developers have a full
understanding about how his
applications are running in production
Infrastructure: release system, monitor
system
16. PracticesC
1. Organize codebase based on applications
2. Use Docker to make environment consistent
3. Integrate Alibaba services into Spring Boot
4. Use Spring Cloud Config & Diamond to manage config
5. Use Maven BOM to manage Java depdencies
6. Apply strict rules on published jar
7. Apply strict naming standard on applictions
8. Split microservices from monolithic
17. 1. Organize codebase based on apps
monolithic monolithic monolithic
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
global jar
Yes, code is reused,
but …
Global jar: each jar is an svn trunk, and
will be deployed into maven repository.
So when we want to release, we usually
create a few branches from different
global jars and one monolithic, which
easily causes collision and release
queue.
18. microservice
local jar local jar
local jar local jar
published jar
microservice
local jar local jar
local jar local jar
published jar
microservice
local jar local jar
local jar local jar
published jar
microservice
local jar local jar
local jar local jar
published jar
local jar and the microservice are in the
same git repo, actually local jar only exists in
maven build and don’t get into maven repo
published jar is the API of an microservice,
it’s semantic versioned, and get into maven
repo.
19. 2. User Docker to make environment consistent
FROM reg.docker.alibaba-inc.com/aone-base/ae-boot-app:latest
COPY ${APP_NAME}.tgz /home/admin/${APP_NAME}.tgz
Alibaba Base Image
AliExpress Base Image
AliExpress Boot Image
FROM
FROM
Boot App
Boot App
Boot App
Boot App
Boot App
FROM
1. the developers always FROM our
latest image, so it’s easy to force
upgrade globally (e.g. for security
issues)
2. As long as the boot images are well
tested, most of the issue about
environment are gone. (thanks to
immutability)
3. we can speed up the release
process by preloading docker app
images
20. 3. Integrate Alibaba services into Spring Boot
<dependency>
<groupId>com.aliexpress.boot</groupId>
<artifactId>spring-boot-starter-hsf</artifactId>
</dependency>
@SpringBootApplication
@EnableHSF
public class DemoApplication{}
@HSFProvider(serviceInterface = UserService.class, serviceVersion = "1.0.1")
public class UserServiceImpl implements UserService{}
Use starter to simply code
23. 4. Use Spring Cloud Config and Diamond to manage config
Binarybuild config
Binary X
Binary Y
Binary ZGlobal
Config
Repo
Binarybuild
Config
Repo
Config
Repo
Config
Repo
Binary
Binary
Binary
immutable
24. diamond-spring-boot-starter
Spring Boot starter for diamond
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>diamond-spring-boot-starter</artifactId>
</dependency>
1. Configure application.properties :
spring.application.name=archimedes-master
spring.application.group=com.aliexpress.archimedes
2. Configure Diamond:
com.aliexpress.archimedes:archimedes-master.properties
archimedes.masterEnabled=true
eureka.client.fetch-registry=true
…
…
3. In java, use the configuration like this:
@Value("${archimedes.masterEnabled}")
private boolean masterEnabled;
@Value("${archimedes.messagingProducerDestination}")
private String messagingProducerDestination;
25. 5. Use Maven BOM to manage Java dependencies
<properties>
<alibaba-spring-boot.version>1.4.0</alibaba-spring-boot.version>
<spring-boot.version>1.4.2.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>alibaba-spring-boot-dependencies</artifactId>
<version>${alibaba-spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.aliexpress.boot</groupId>
<artifactId>spring-boot-starter-hsf</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>diamond-spring-boot-starter</artifactId>
</dependency>
</dependencies>
The BOM defines a set of dependencies
people usually use, so when they import it,
1.they don’t need to care about the specific
version of a dependency,
2.and don’t need to care about dependency
collision.
27. 6. Apply strict rules on published jar
microservice
local jar local jar
local jar local jar
published jar
Published jar is the API of a microservice,
usually depended by other microserivces,
it MUST be clean!
28. microservice
local jar local jar
local jar local jar
published jar
1. do not depend on log impl (log4j, logback etc.)
2. do not have log config (log4j.xml, logback.xml)
3. do not depend on legacy jars
4. do not depend on SNPAHOTs
5. …
<parent>
<groupId>com.aliexpress</groupId>
<artifactId>aliexpress-published-lib-parent</artifactId>
<version>3-SNAPSHOT</version>
</parent>
30. 7. Apply strict naming standard on applications
[ae]-[product]-[domain/scenario]-[classifier]
Classifier
1 s - Service, this application expose HSF service
2 f - Front-end Web Application, expose 80 port to internet.
3 b - Back-end Web Application, expose 80 port to intranet
4 d - Data Flow Application, consumes messages, producer messages, or writes data to DB.
Product
An enumerable project name, we are very strict on adding new product name.
e.g
ae-fileserver2-sync-s
ae-fileserver2-upload-f
ae-fileserver2-admin-b
we have hundreds of applications, it’s
important to name them in a consistent
way so it’s easy to communicate.
all the systems use this name:
monitoring system, release system
and we can control the problem domain
31. 8. Split microservices from monolithic
• Developers can learn step by step.
• Much lower risk, easy to switch traffic back.
• Heavily rely on the monitoring system.