1 Distributed
1.1 What is distributed
1.2 The difference between distributed and clusters
It turns out that there is only one chef in the small restaurant, who cuts vegetables, washes vegetables, prepares ingredients and stir-frys them all. Later, there were more customers, and a chef in the kitchen was too busy, so he hired another chef. Both chefs could cook the same dishes. The relationship between these two chefs was a cluster. In order to let the chef concentrate on cooking and do the best of the dishes, he hired a side dish to be responsible for cutting vegetables, preparing dishes, and preparing ingredients. The relationship between the chef and the side dish is distributed, and one side dish is too busy, so he hired a side dish, and the relationship between the two side dish is a cluster.
2. Build a distributed project
Preparation tools: eclipse, VMwarm equipped with CentOS7 system, zookeeper.... The most important thing is a three-year-old elderly machine.
1 First create a maven project of the parent class, and the packaging method is pom.
Create a parent class maven project in eclipse, and the packaging method is pom. Why create a parent class maven project? Because you want to use this maven project to manage various jar package versions, if the subclass wants the jar package directly and the parent class, you can do it. xml
<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.itqf</groupId> <artifactId>sing-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <!-- Define the version of all jar packages--> <properties> <junit.version>4.12</junit.version><spring.version>4.2.4.RELEASE</spring.version><mybatis.version>3.2.8</mybatis.version><mybatis.spring.version>1.2.2</mybatis.spring.version><mybatis.paginator.version>1.2.15</mybatis.paginator.version><mysql.version>5.1.32</mysql.version><slf4j.version>1.6.4</slf4j.ve rsion><jackson.version>2.4.2</jackson.version><druid.version>1.0.9</druid.version><httpclient.version>4.3.5</httpclient.version><jstl.version>1.2</jstl.version><servlet-api.version>2.5</servlet-api.version><jsp-api.version>2.0</jsp-api.version><joda-time.version>2.5</joda-time.version><commons-lang3.ve rsion>3.3.2</commons-lang3.version><commons-io.version>1.3.2</commons-io.version><commons-net.version>3.3</commons-net.version><pagehelper.version>3.4.2-fix</pagehelper.version><jsqlparser.version>0.9.1</jsqlparser.version><commons-fileupload.version>1.3.1</commons-fileupload.version><jedis.version>2.7 .2</jedis.version><solrj.version>4.10.3</solrj.version><dubbo.version>2.5.3</dubbo.version><zookeeper.version>3.4.7</zookeeper.version><zkclient.version>0.1</zkclient.version><activemq.version>5.11.2</activemq.version><freemarker.version>2.3.23</freemarker.version><quartz.version>2.2.2</quartz.version> </properties> <!-- Manage jar packages used in all projects, without real dependencies--> <dependencyManagement> <dependencies><!-- Time operation component--><dependency><groupId>joda-time</groupId>
2 Create a maven aggregation project.
2.1 Create a maven aggregation project and inherit the parent project.
Aggregation engineering: The controller layer, view layer, etc. in the project can be independently formed into a project, and finally integrated into a project when it is finally run.
pom.xml
<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> <parent> <groupId>com.itqf</groupId> <artifactId>sing-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.itqf</groupId> <artifactId>sing-manager</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <dependencies> <dependency> <groupId>com.itqf</groupId> <artifactId>sing-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependencies> <build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><port>8083</port><path>/</path></configuration></plugin></plugins> </build> <modules> <modules>sing-manager-pojo</module> <module>sing-manager-interface</module> <module>sing-manager-service</module> <module>sing-manager-mapper</module> </modules></project>
2.2 Create a maven Module in the aggregation project and name it sping-manager-pojo (entity class layer).
pojo is a normal jar format and does not need to rely on the parent project.
pom.xml
<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> <parent> <groupId>com.itqf</groupId> <artifactId>sing-manager</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sing-manager-pojo</artifactId></project>
2.3 Create a maven Module in the aggregation project and name the spring-manager-mapper (dao layer). Rely on pojo in the pom.xml file. Because the mapper layer method returns an entity class object, pojo needs to be used.
Import dependency jar packages.
xml
<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> <parent> <groupId>com.itqf</groupId> <artifactId>sing-manager</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sing-manager-mapper</artifactId> <!-- Dependency pojo --> <dependencies> <dependency> <groupId>com.itqf</groupId> <artifactId>sing-manager-pojo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- Mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis.spring.version}</version></dependency><dependency><gro upId>com.github.miemiedev</groupId><artifactId>mybatis-paginator</artifactId><version>${mybatis.paginator.version}</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>${pagehelper.version}</version></dependency><!-- MySql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- Connection pool--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency> </dependencies></project> 2.4 Create a spring-manager-interface (interface) in the aggregation project and place all service interfaces into an independent project. If the return value of the method in the interface is an entity class, pojo is required. Therefore, it depends on pojo xml in pom.
<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> <parent> <groupId>com.itqf</groupId> <artifactId>sing-manager</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sing-manager-interface</artifactId> <dependencies> <dependency> <groupId>com.itqf</groupId> <artifactId>sing-manager-pojo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
2.5 Create spring-manager-service (interface implementation class) in the aggregation project. The packaging method is war
Because the controller layer is separated from the service layer, when running and starting, the controller and service should be published separately using tomcat, and all the configuration files required in the aggregation project are placed into the service, so that all the configuration files will be loaded and integrated when Tomcat is started.
Configuration File
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration></configuration>
db.properties
db.driver=com.mysql.jdbc.Driverdb.url=jdbc:mysql://localhost:3306/taotao?characterEncoding=UTF-8db.username=rootdb.password=root
applicationContext-tx.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:tx="http://www.springfr amework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <bean id="txManager"> <property name="dataSource" ref="dataSource"></property> </bean> <tx:advice id="adviceId" transaction-manager="txManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> <tx:method name="get*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="adviceId" pointcut="execution(* com.itqf.service..*.*(..))"/> </aop:config> </beans>
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:property-placeholder location="classpath:resource/*.properties"/> <bean id="dataSource"> <property name="driverClassName" value="${db.driver}"></property> <property name="url" value="${db.url}"></property> <property name="username" value="${db.username}"></property> <property name="password" value="${db.password}"></property> <property name="maxActive" value="10"></property> <property name="minIdle" value="5"></property> </bean> <bean> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property> </bean> <bean> <property name="basePackage" value="com.itqf.mapper"></property> </bean></beans> applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.itqf.service"></context:component-scan> </beans>
pom.xml
<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> <parent> <groupId>com.qianfeng</groupId> <artifactId>sing-manager</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sing-manager-service</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.qianfeng</groupId> <artifactId>sing-manager-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.qianfeng</groupId> <artifactId>sing-manager-mapper</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${sp ring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring- jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframewo rk</groupId><artifactId>spring-jms</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency> </dependencies></project>Final engineering structure
3 Use dubbo to publish service
Think first?
Mall websites like Taobao and JD can not only log in from the PC side, but also from the mobile phone side. How is it implemented? Write two controllers? That is definitely not. Who will have nothing to do when you have nothing to do? Then this requires the use of SOA (service-oriented architecture). When we write a project using distributed, there will be many systems to call each other. If you call back and forth, the code structure will be very confusing. Here we use dubbo to manage to solve the problem of too many publishing services and not being clear about it.
What is SOA
SOA is a design method that includes multiple services, and services will eventually provide a series of functions through cooperation. A service usually exists in an independent form in an operating system process. Services communicate through the network, rather than in-process calls.
For example, you have many services now: news services (providing news release, viewing, modification, deletion), order services (order addition, order modification, order viewing, order deletion, etc.) financial services (revenue, expenditure, statistics, etc.) employee services (new, modification, viewing, statistics) attendance services (sign-in, sign-in, return, export, statistics, etc.) sales services (sell reporting, sales statistics.)
dubbo
What is dubbo (a management tool for resource scheduling and governance center)
With the development of the Internet, the scale of website applications has been continuously expanded, and conventional vertical application architectures can no longer cope with it. Distributed service architectures and mobile computing architectures are imperative. A governance system is urgently needed to ensure the orderly evolution of the architecture.
Single application architecture
Vertical application architecture
Distributed Service Architecture
Flow computing architecture
Construction of Dubbo environment:
Node role description:
Call relationship description:
Here we mainly come to the Registry Center (Registry), and we use Zookeeper to act as the Registry Center.
Deploy the registry in the Linux environment, Zookeeper
The first step is of course to turn on the virtual machine, so I will do it in CentOS7.
Get a Zookeeper compressed package online, mine is zookeeper-3.4.6.tar.gz
Paste in /opt directory and decompress. (The jdk environment is required. If there is no jdk environment, install a jdk first)
Enter the zookeeper-3.4.6 directory and create a folder called data.
Rename zoo_sample.cfg in the ./conf directory to zoo.cfg Modify the data attribute in zoo.cfg: dataDir=/opt/zookeeper-3.4.6/data
Step 7:
Note that after zookeeper is started, you must turn off the firewall!!! That's it.
Add configuration file to the service applicationContext-service.xml to publish the service
<!-- Use dubbo to publish the service --> <!-- Indicate the project where the service is located --> <dubbo:application name="sing-manager"/> <!-- Indicate the registry address is the IP address in Linux plus the port number, and the default port number of zookeeper is 2181 --> <dubbo:registry protocol="zookeeper" address="10.0.117.198:2181" ></dubbo:registry> <!-- Expose the service to a certain port port port number, select a port that is not occupied --> <dubbo:protocol name="dubbo" port="20888"></dubbo:protocol> <!-- Expose the service to a certain port port port number, select a port that is not occupied --> <dubbo:protocol name="dubbo" port="20888"></dubbo:protocol> <!-- Ref is the name of the Service object created by the Spring container --> <dubbo:service interface="com.itqf.service.ItemService" ref="itemServiceImpl" timeout="6000000"></dubbo:service>
Import packages in service pom.xml
<!-- dubbo-related--><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><!-- Exclude dependencies --><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>spring</artifactId></exclusion><exclusion><groupId>org.jboss.netty</groupId><artifactId>netty</artifactId></exclusion></exclusions >/dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></dependency><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId></dependency>
4 Create a spring-manager-controller, which is on the same level as the aggregate project. Import dependencies.
The consoler needs to use dubbo to access the service published by the service layer. To use the Tomcat server for publishing, of course, springmvc is also needed.
xml
<dependencies> <!-- Just rely on the service interface--> <dependency> <groupId>com.qianfeng</groupId> <artifactId>sing-manager-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${sp ring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring- jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframewo rk</groupId><artifactId>spring-jms</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency> <!-- JSP-related--><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jsp-api</artifactId><scope>provided</scope></dependency><!-- dubbo related--><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><!-- Exclude dependencies --><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>spring</artifactId></exclusion><exclusion><groupId>org.jboss.netty</groupId><artifactId>netty</artifactId></exclusion></exclusions >/dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></dependency><dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId></dependency> </dependencies> <build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><port>8081</port><path>/</path></configuration></plugin></plugins> </build> spingmvc.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:tx="http://www.springfr amework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.itqf.controller"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven> <bean> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--Specify the project--> <dubbo:application name="sping-manager-controller"/> <!--Specify the registration center--> <dubbo:registry protocol="zookeeper" address="10.0.117.198:2181"></dubbo:registry> <!--Calling the service--> <dubbo:reference interface="com.itqf.service.ItemService" id="itemService"></dubbo:reference> </beans>
Structural diagram:
5 Create a spring-common
This is a place I need to use to place tools specifically, which is used to place some public needs; pom.xml
<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> <parent> <groupId>com.itqf</groupId> <artifactId>sing-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.itqf</groupId> <artifactId>sing-common</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies><!-- Time Operation Component--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${joda-time.version}</version></dependency><!-- Apache Tool Components--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons-lang3.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifact Id>commons-io</artifactId><version>${commons-io.version}</version></dependency><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>${commons-net.version}</version></dependency><!-- Jackson Json Processing Toolkit--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency></dependencies> </project>6 Test
Okay, this pseudo-distributed project has been built. The next important point is that the parent project, the aggregation project of the spring-manager, and the spring-common need to be installed in the local warehouse. Otherwise, an error will be reported when starting the project and the parent project or other projects cannot be found.
Final drawing:
Summarize:
After several hours of hard work, I finally built it. The old man who was going to be tired and exploded. If there are any mistakes or shortcomings, please be willing to do so.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.