cloud Alibaba project
Architecture evolution
Monomer architecture
- The database and cache are shared in one program, and the deployment is simple
- The disadvantages are obvious, and the code coupling seriously affects the whole body
Vertical Architecture
- Advantages: service, independent deployment, easy horizontal expansion
- Disadvantages: complex construction, complex relationship between services and difficult maintenance
SOA Architecture
- At first, there was a function division of blocks, but it still called each service node through a bus
- Advantages: it provides a unified route for the underlying services, which is convenient to call
- Disadvantages: it is difficult to implement, and there is coupling between different architectures
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-rNaKHa12-1638451334849)(springcloudalibaba project. assets/image-20211202193441209.png)]
Microservice architecture
- Compared with SOA, the entry of microservices began to change, no longer directly accessing programs, but dispatching and forwarding through gateways
- The filtered requests will be forwarded to the corresponding microservices. Each service is independent and runs on different machines, communicating with rest or http
Cognitive Domain Driven Design
Advantages: entrance authentication, detailed function distribution and excellent performance
Disadvantages, complexity and difficulty of the project, information exposure, complex links and other problems
Understanding of Domain Driven Design
Understand domain concepts, learn domain knowledge, and model the domain
- Analysis domain model, deduction entity, value object, domain service
- Find the aggregation boundary and reduce the service coupling
- Provide storage warehouse for coupling and data persistence
- Practice DDD and push it to refactoring
Classic layered architecture
unscramble
- User Interface the User Interface layer receives user instructions and displays information
- The applcation application layer Controller provides service interfaces externally and calls the domain layer internally
- The Domain domain layer is equivalent to an entity object, and the Domain model corresponds to a table in the database
- Infrastructure infrastructure layer provides common basic capabilities, communication capabilities and persistence mechanisms for other layers
Traditional development:
The database tables will be designed before the start to meet the requirements. Later modifications will affect the function and even the overall structure
Domain Driven Design:
At the initial stage, the business is concerned, and persistence is only for the later stage of business design
E-commerce engineering business interpretation, micro service module splitting
Tips
The best way to learn domain knowledge is reference and reference
Simple understanding diagram
Microservice module splitting
Project portal and user authentication micro service
The gateway is the only entrance to the microservice architecture
This is the facade of e-commerce
Involve
- Authority authentication
- Service call
- Current limiting, etc
Main function service module
Account, commodity, order, logistics
- Reasonable division of micro services
- Try to reduce the dependency of each service and the intersection with other services, preferably no intersection
E-commerce development
Implement common modules
step
Create project -- > import dependency – > write configuration
The parent project creates the corresponding dependencies required for e-commerce-springcloud import
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hyc.ecommerce</groupId> <artifactId>e-commerce-springcloud</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>e-commerce-common</module> <module>e-commerce-mvc-config</module> </modules> <packaging>pom</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <properties> <!-- Spring Cloud Hoxton.SR8 rely on --> <spring-cloud.version>Hoxton.SR8</spring-cloud.version> <!-- spring cloud alibaba rely on --> <spring-cloud-alibaba.version>2.2.4.RELEASE</spring-cloud-alibaba.version> </properties> <dependencies> <!-- lombok The tool dynamically replaces annotations with specific code during code compilation, IDEA Need to add lombok plug-in unit --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.11</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.6.0</version> </dependency> <!-- introduce jwt--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.10.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.10.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.10.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies> <!-- Project dependency management the parent project only declares dependencies, and the child project needs to specify the required dependencies(Version information can be omitted) --> <dependencyManagement> <dependencies> <!-- spring cloud rely on --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba rely on --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- Configure remote warehouse --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
Common sub module common library commons
e-commerce-common module
Dependencies are as follows
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>e-commerce-springcloud</artifactId> <groupId>com.hyc.ecommerce</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>e-commerce-common</artifactId> <!-- Module name and description information --> <name>e-commerce-common</name> <description>General module</description> </project>
In this way, many data models will be put into the module to be used by the function service module. First, create and respond uniformly, and then the corresponding data model will be added
Create response format
/** * @author : Leng Huanyuan * @date : 2021/12/2 * @context: General response definition * { * "code":1 * "message":hyc * "data":{} * } */ @Data @NoArgsConstructor @AllArgsConstructor public class CommonResponse<T> implements Serializable { //Corresponding code private Integer code; //Return message information description private String message; public CommonResponse(Integer code, String message) { this.code = code; this.message = message; } //Generic content data private T Data; }
Common sub module web unified return and global exception handling e-commerce-mvc-config
The e-commerce-mvc-config module is mainly used to isolate functions. Some service modules, such as the gateway, cannot be started with web dependencies. In this way, it can import commons to isolate the corresponding functions of services
Dependencies are as follows
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>e-commerce-springcloud</artifactId> <groupId>com.hyc.ecommerce</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>e-commerce-mvc-config</artifactId> <!-- Module name and description information --> <name>e-commerce-mvc-config</name> <description>General configuration module</description> <dependencies> <!-- introduce Web function --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.hyc.ecommerce</groupId> <artifactId>e-commerce-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
Write annotation IgnoreResponseAdvice
IgnoreResponseAdvice ignores the definition of the unified response annotation, that is, it does not need to use the CommonsResponese class defined by us to use this annotation
Realize uniform response and uniform ignore response annotation
/** * @author : Leng Huanyuan * @date : 2021/12/2 * @context: Realize uniform response and uniform ignore response annotation * @params : null * @return : * @return : null */ @RestControllerAdvice(value = "com.hyc.ecommerce") //Implement the interface suggested by the responder public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { //Determine whether the annotation IgnoreResponseAdvice is available on the class if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) { return false; } //Judge whether the annotation IgnoreResponseAdvice is available on the method if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) { return false; } //If none, it means to use the public return format return true; } //How to use it if it needs to be used @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //Define the final return object CommonResponse<Object> response = new CommonResponse<>(0, ""); //If it is equal to null, it means there is no direct return if (o == null) { return response; //If it is equal to the public return type, convert o to the public return commonresponse < > } else if (o instanceof CommonResponse) { response = (CommonResponse<Object>) o; //If not, the response content is set to the object } else { response.setData(o); } return response; } }
Global exception handling
GlobalExceptionAdvice handles global exceptions. If a request occurs, an exception will be returned to a unified result
/** * @author : Leng Huanyuan * @date : 2021/12/2 * @context:Global exception handling * @params : null * @return : * @return : null */ @Slf4j @RestControllerAdvice public class GlobalExceptionAdvice { //This annotation means exception handling, and the parameter is the exception you want to catch @ExceptionHandler(value = Exception.class) public CommonResponse<String> handlerCommerceException(HttpServerRequest req, Exception ex) { //Initializes a public response object CommonResponse<String> response = new CommonResponse<>( -1, "business error" ); //Add the error message to the message header response.setData(ex.getMessage()); //Control the background print error log and return the public response body to give the caller a prompt log.error("commerce service has error:[{}]", ex.getMessage(), ex); return response; } }