With the development of the Internet, the scale of website applications keeps expanding, and the conventional vertical application architecture can no longer cope with it. The distributed service architecture and mobile computing architecture are imperative, and a governance system is urgently needed to ensure the orderly evolution of the architecture.
First, a picture
Speaking of Dubbo, I believe everyone will not be unfamiliar! Alibaba is an open source high-performance service framework, which enables applications to realize the output and input functions of services through high-performance RPC, and can integrate seamlessly with Spring framework.
Node roles:
- Provider: exposes the service Provider of the service
- Consumer: Service Consumer that invokes the remote service
- Registry: A Registry where services are registered and discovered
- Monitor: monitors the number and duration of service invocation
- Container: service running Container
Second, implementation ideas
Today, we take the process of a user selecting a product and placing an order, split it into 3 business services: user center, product center, order center, and use Springboot + Dubbo to achieve a small Demo!
The service interaction flow is as follows:
This article mainly introduces Springboot and Dubbo framework integration and development practice, and the real business service separation is a very complex process, much more complex than we introduced this, the above mentioned three services are just for the project demonstration, do not bother too much why such separation!
Ok, nonsense is not much to say, below we open masturbation!
- 1. Create four centos7s on the VM and install ZooKeeper on any of them
- 2. Build microservice projects and write code
- 3. Deploy microservices on centos7
- 4. Remote service invocation test
Zookeeper installation
Before using Dubbo, we need a registry. Currently, there are registries available for Dubbo, such as ZooKeeper, Nacos, etc. Zookeeper is generally recommended!
Before installing Zookeeper, you need to install and configure JDK. Oracle Java8 SE is used on the local computer.
- Install JDK (already installed and can be ignored)
Yum -y install Java -- 1.8.0 comes with itsCopy the code
- Check the Java installation
java -version
Copy the code
- After installing the JDK, download and install Zookeeper
Create a ZooKeeper foldercd/usr mkdir Zookeeper Downloads wget of ZooKeeper-3.4.14 http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz extract tar ZXVF. - Zookeeper - 3.4.14. Tar. Gz < / pre >Copy the code
- Create data and log directories
Create directories for storing data and logscd /usr/zookeeper/
mkdir data
mkdir logConf file zoo_sample. CFG and rename it zoo.cfgcd conf/
cp zoo_sample.cfg zoo.cfg</pre>
Copy the code
- Configuration zookeeper
# edit zoo. CFG file
vim zoo.cfg
Copy the code
- Start the Zookeeper
# start the Zookeeper
./zkServer.sh start
# Query the Zookeeper status
./zkServer.sh status
# Disable the Zookeeper state
./zkServer.sh stop</pre>
Copy the code
If the following information is displayed, the startup is successful.
Iv. Project Introduction
- Springboot version: 2.1.1.release
- Zookeeper version: 3.4.14
- Dubbo version: 2.7.3
- Mybtais-plus version: 3.0.6
- Database: mysqL-8
- Build tool: Maven
- Service module: user center, commodity center, order center
5. Code practice
5.1. Initialize the database
First, on the mysql client, create three databases, namely, Dianshang-user, Dianshang-platform and dianshang-Business.
- In the Dianshang-user database, create the user table TB_user and initialize the data
- In the Dianshang-platform database, create the commodity table TB_product and initialize the data
- In the Dianshang-platform database, create the order table TB_ORDER and order detail table tb_ORDER_detail
5.2. Create a project
After the database table design is complete, create a Springboot project named DianShang under IDEA.
The final directory is as follows:
Directory structure description:
- Dianshang-common: mainly houses some common libraries that all services can rely on
- Dianshang-business: Order center, where
api
The module mainly provides the Dubbo service exposure interface,provider
A module is aspringboot
Project to provide service processing operations - Dianshang-user: user center, where
api
The module andprovider
Module, designed similarly - Dianshang-platform: Merchandise center, where
api
The module andprovider
Module, designed similarly
Add dubbo and ZooKeeper clients to the parent POM file and make them available to all dependent projects.
<! -- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> The < version > 1.18.4 < / version > < scope > provided < / scope > < / dependency > <! -- Dubbo Spring Boot Starter --> <dependency> <groupId>org.apache.dubbo</groupId> < artifactId > dubbo - spring - the boot - starter < / artifactId > < version > 2.7.3 < / version > < / dependency > <! -- Using ZooKeeper as the registry, Zookeeper </groupId> <artifactId> Zookeeper </artifactId> <version>3.4.13</version> <exclusions> <groupId>org.slf4j</groupId> <artifactId> slf4J-api </artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId>
<artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <! > <dependency> <groupId>org.apache.curator</groupId> < artifactId > curator - framework < / artifactId > < version > 4.2.0 < / version > < / dependency > < the dependency > < the groupId > org. Apache. Curator < / groupId > < artifactId > curator - recipes < / artifactId > < version > 4.2.0 < / version > < / dependency >Copy the code
Tips: For example, in this example, the ZooKeeper server version is 3.4.14. Therefore, the zooKeeper file library should be the same as the zooKeeper file library. If you rely on the 3.5.x version of ZooKeeper, the project will start with all kinds of bogey errors!
5.3. Create a User center project
In IDEA, create the Dianshang-user submodule and rely on the Dianshang-common module
<dependencies> <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-common</artifactId> The < version > 1.0.0 < / version > < / dependency > < / dependencies >Copy the code
Meanwhile, dianshang-user-provider and Dianshang-user-API modules are created.
- Dianshang-user-api: mainly provides interface exposure to other services
- Dianshang-user-provider: similar to a Web project, mainly responsible for basic services
crud
While relying ondianshang-user-api
The module
5.3.1. Configure the Dubbo service
Configure the dubbo service in the application. Yml file of dianshang-user-provider as follows:
User center service port
server:
port: 8080
# data source configuration
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: "jdbc:mysql://localhost:3306/dianshang-user"
username: root
password: 111111
# dubbo configuration
dubbo:
scan:
Write the package name according to your actual situation
base-packages: org.project.dianshang.user
protocol:
port: 20880
name: dubbo
registry:
#zookeeper registration center addressAddress: zookeeper: / / 192.168.0.107:2181Copy the code
5.3.2. Write service exposure interfaces and implementation classes
In the dianshang-user-API module, create a UserApi interface and return the parameter object UserVo!
Public interface UserApi {/** * query user information * @param userId * @return
*/
UserVo findUserById(String userId);
}
Copy the code
UserVo needs to be serialized as follows:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) public class UserVo implements Serializable { private static final long serialVersionUID = 1L; /** * userId */ private String userId; /** * private String userName; }Copy the code
In the Dianshang-user-Provider module, write the UserApi interface implementation class as follows:
@Service(interfaceClass =UserApi.class)
@Component
public class UserProvider implements UserApi {
@Autowired
private UserService userService;
@Override
public UserVo findUserById(String userId) {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq("user_id",userId);
User source = userService.getOne(queryWrapper);
if(source! = null){ UserVo vo = new UserVo(); BeanUtils.copyProperties(source,vo);
return vo;
}
returnnull; }}Copy the code
The annotation @ Service refers to the org. Apache. Dubbo. Config. The annotation. Under the Service annotations, rather than under the Spring annotations!
Next, let’s go ahead and create the Goods Center project!
5.4. Create commodity Center project
Similar to the user-centric project, in IDEA, the Dianshang-platform submodule is created and relies on the Dianshang-common module
<dependencies> <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-common</artifactId> The < version > 1.0.0 < / version > < / dependency > < / dependencies >Copy the code
Meanwhile, the dianshang-platform-provider and dianshang-platform-API modules are created.
- Dianshang-platform-api: mainly provides interface exposure to other services
- Dianshang-platform-provider: similar to a Web project, mainly responsible for basic services
crud
While relying ondianshang-platform-api
The module
5.4.1 configuring the Dubbo service
Configure the dubbo service in the application. Yml file of dianshang-platform-provider as follows:
User center service port
server:
port: 8081
# data source configuration
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: "jdbc:mysql://localhost:3306/dianshang-platform"
username: root
password: 111111
# dubbo configuration
dubbo:
scan:
Write the package name according to your actual situation
base-packages: org.project.dianshang.platform
protocol:
port: 20881
name: dubbo
registry:
#zookeeper registration center addressAddress: zookeeper: / / 192.168.0.107:2181Copy the code
5.4.2. Write service exposure interfaces and implementation classes
In the dianshang-platform-API module, create a ProductApi interface and return the parameter object ProductVo!
Public interface ProductApi {/** * Query product information * @param productId * @ by commodity IDreturn
*/
ProductVo queryProductInfoById(String productId);
}
Copy the code
ProductVo needs to be serialized as follows:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) public class ProductVo implements Serializable { private static final long serialVersionUID = 1L; /** ID*/ private String productId; /** private String productName; /** private BigDecimal productPrice; }Copy the code
In the dianshang-platform-Provider module, write the ProductApi interface implementation class as follows:
@Service(interfaceClass = ProductApi.class) @Component public class ProductProvider implements ProductApi { @Autowired private ProductService productService; @override public ProductVo queryProductInfoById(String productId) {// Query Product information by Product IDsource = productService.getById(productId);
if(source! = null){ ProductVo vo = new ProductVo(); BeanUtils.copyProperties(source,vo);
return vo;
}
returnnull; }}Copy the code
Next, we continue to create the order center project!
5.5. Create an order Center project
Similar to the Goods Center project, in IDEA, the Dianshang-Business submodule is created and relies on the Dianshang-common module
<dependencies> <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-common</artifactId> The < version > 1.0.0 < / version > < / dependency > < / dependencies >Copy the code
Meanwhile, dianshang-business-Provider and Dianshang-business-API modules are created.
- Dianshang-business-api: primarily provides interface exposure to other services
- Dianshang-business-provider: Similar to a Web project, mainly responsible for the basic business
crud
While relying ondianshang-business-api
The module
5.5.1. Configure the Dubbo service
Configure the dubbo service in the application. Yml file of dianshang-business-provider as follows:
User center service port
server:
port: 8082
# data source configuration
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: "jdbc:mysql://localhost:3306/dianshang-business"
username: root
password: 111111
# dubbo configuration
dubbo:
scan:
Write the package name according to your actual situation
base-packages: org.project.dianshang.business
protocol:
port: 20882
name: dubbo
registry:
#zookeeper registration center addressAddress: zookeeper: / / 192.168.0.107:2181Copy the code
5.5.2. Write service exposure interfaces and implementation classes
In the dianshang-business-API module, create an OrderApi interface and return the parameter object OrderVo!
Public interface OrderApi {/** * query user order information by userId * @param userId * @return
*/
List<OrderVo> queryOrderByUserId(String userId);
}
Copy the code
Where OrderVo needs to implement serialization as follows:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) public class OrderVo implements Serializable { private static final long serialVersionUID = 1L; /** orderId */ private String orderId; /** order number */ private String orderNo; /** Order amount */ private BigDecimal orderPrice; /** orderTime */ private Date orderTime; }Copy the code
In the Dianshang-business-Provider module, write the OrderApi interface implementation class as follows:
@Service(interfaceClass = OrderApi.class) @Component public class OrderProvider implements OrderApi { @Autowired private OrderService orderService; @Override public List<OrderVo> queryOrderByUserId(String userId) { QueryWrapper<Order> queryWrapper = new QueryWrapper<Order>(); queryWrapper.eq("user_id",userId);
List<Order> sourceList = orderService.list(queryWrapper);
if(! CollectionUtils.isEmpty(sourceList)){
List<OrderVo> voList = new ArrayList<>();
for (Order order : sourceList) {
OrderVo vo = new OrderVo();
BeanUtils.copyProperties(order, vo);
voList.add(vo);
}
return voList;
}
returnnull; }}Copy the code
At this point, service exposure interfaces have been developed for three projects! Next we’ll write how to make a remote call!
5.6. Remote Invocation
5.6.1 Write and create order service
In the dianshang-business-provider module, dianshang-business-API and dianshang-user-API are first relied on before writing and creating the order interface, as follows:
<! <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-platform-api</artifactId> The < version > 1.0.0 < / version > < / dependency > <! --> <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-user-api</artifactId> The < version > 1.0.0 < / version > < / dependency >Copy the code
In the dianshang-business-provider module, write the order creation service as follows:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private OrderDetailService orderDetailService;
@Reference(check =false)
private ProductApi productApi;
@Reference(check =false) private UserApi userApi; /** * new */ @jwtignore @requestMapping (value ="/add")
public boolean add(String productId,String userId){
LocalAssert.isStringEmpty(productId,"Product Id cannot be empty");
LocalAssert.isStringEmpty(userId,"User Id cannot be empty");
ProductVo productVo = productApi.queryProductInfoById(productId);
LocalAssert.isObjectEmpty(productVo,"No product information found");
UserVo userVo = userApi.findUserById(userId);
LocalAssert.isObjectEmpty(userVo,"No user information found");
Order order = new Order();
order.setOrderId(IdGenerator.uuid());
order.setOrderNo(System.currentTimeMillis() + "");
order.setOrderPrice(productVo.getProductPrice());
order.setUserId(userId);
order.setOrderTime(new Date());
orderService.save(order);
OrderDetail orderDetail = new OrderDetail();
orderDetail.setOrderDetailId(IdGenerator.uuid());
orderDetail.setOrderId(order.getOrderId());
orderDetail.setProductId(productId);
orderDetail.setSort(1);
orderDetailService.save(orderDetail);
return true; }}Copy the code
@ the Reference of these comments, it is to belong to org. Apache. Dubbo. Config. The annotation. The Reference of the annotations, said remote depend on service.
Check =false indicates that the remote service status check is not performed when the service is started. The purpose of setting this parameter is to prevent the current service startup failure. For example, the user center project is not started successfully, but the order center depends on the user center.
5.6.2 Compile users to query their own order information
Similarly, dianshang-user-provider module relies on Dianshang-business-API and Dianshang-user-API before writing the interface for users to query their own order information, as follows:
< the groupId > org. Project. The demo < / groupId > < artifactId > dianshang - business - API < / artifactId > < version > 1.0.0 < / version > </dependency> <dependency> <groupId>org.project.demo</groupId> <artifactId>dianshang-user-api</artifactId> <version>1.0.0</version> </dependency></pre> In the 'dianshang-user-provider' module, write an interface for users to query their own order information, as follows: <p style=" margin-bottom: 0.5em; font-family: Menlo, Monaco, Consolas, " Courier New" , monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; 1.5 em margin: 0 px 0 px; font-size: 14px; The line - height: 1.5 em. word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;" >@RestController @RequestMapping("/user") public class UserController { @Reference(check =false) private OrderApi orderApi; /** * by user ID, * @param userId * @return */ @requestMapping ("/list") public list <OrderVo> queryOrderByUserId(String userId){ return orderApi.queryOrderByUserId(userId); }}Copy the code
At this point, the remote service invocation is written!
Six, service test
Before deploying the project to the server, let’s test locally to see if all the services work.
- Start the User Center
dianshang-user-provider
- Continue to launch the commodity center
dianshang-platform-provider
- Then start the order center
dianshang-business-provider
Finally, let’s test whether the service interface works as expected.
Open a browser, type http://127.0.0.1:8082/order/add? ProductId =1&userId=1 test create order interface, page running results display normal!
Let’s look at the database, is the order generated?
Ok! Very clear to see, the data has gone in, no problem!
We’ll test the orders in the center of the user query interface, enter http://127.0.0.1:8080/user/list? UserId =1, the page runs as follows!
At this point, the local service test has basically passed!
7. Server deployment
Now that we’ve covered building, developing, and testing services, how do you deploy them on the server side?
First of all, modify the application. Yml file of each project, change the data source address and Dubbo registry address to the online connected address, and then use maven tool under the dianshang directory to execute the following command to package the whole project!
mvn clean install
You can also use maven to configure clean install for package execution in the IDEA environment.
Copy dianshang-user-provider. Jar, dianshang-platform-provider. Jar, and Dianshang-business-provider.
This server uses CentOS7. There are four servers in total, one of which deploys ZooKeeper and the other three deploys three microservice projects.
Log in to the server and enter the following command to ensure that the JDK is installed!
java -version
Turn off the firewall on all servers and allow port access!
systemctl stop firewalld.service
Copy the code
Systemctl disable firewalld.service
- The user center service is started
service.log
(VM IP address: 192.168.0.108)
nohup java -jar dianshang-user-provider.jar > service.log 2>&1 &
- The commodity center service is started, and the log information is output to
service.log
(VM IP address: 192.168.0.107)
nohup java -jar dianshang-platform-provider.jar > service.log 2>&1 &
- The order center service is started and the log information is output to
service.log
(VM IP address: 192.168.0.109)
nohup java -jar dianshang-business-provider.jar > service.log 2>&1 &
Copy the code
Open a browser, type http://192.168.0.109:8082/order/add? ProductId =1&userId=1 test create order interface, page running results display normal!
We’ll test the orders in the center of the user query interface, enter http://192.168.0.108:8080/user/list? UserId =1, the page runs as follows!
You can clearly see the output of two messages, the second order is generated by the test environment server and the first is generated by the local development environment.
At this point, the server deployment is almost complete!
In a production environment, multiple ZooKeeper servers may be required to ensure high availability, at least two servers to deploy service services, and routing through load balancing.
Eight, summary
The whole article is quite long, mainly around the integration of SpringBoot + Dubbo. Remote service invocation via annotation development is as easy as traditional SpringMVC development. Of course, dubbo service invocation via XML configuration is also possible, which will be covered later.
At the same time, it also introduces the deployment of the server, from which we can see that although the development is simple, how to ensure the high availability of the service has become the top task of the developers because of the distributed deployment. Therefore, although the development of distributed micro-service is simple, how to ensure the high availability of the deployed service? Operation and maintenance will bring many challenges!