preface

At present, more and more Internet companies are still servitizing their own projects, which is indeed a trend of future project development. At this point, students can quickly learn to use the PREVIOUS SSM project.

Discussion on Distributed Architecture

The name distributed architecture alone may sound lofty, but it’s easier to understand from a historical perspective.

Let’s take an e-commerce system:

Single system

E65B5547-AF84-4D31-836D-72892C7AC7EA.png


At this point all the business logic can be satisfied in one project.

Vertical split – multiple applications

[email protected]



Nginx

SOA as a service

When the whole system and development is large enough, such as an e-commerce system, there are:

  • The user’s system
  • Order system
  • The payment system
  • Logistics system

Such system. If you have to go back online every time you change one of these systems then the coupling is too severe.

Therefore, the whole project needs to be divided into a number of independent applications, which can be independently developed online to achieve rapid iteration.

dubbo.png

As shown in the figure above, each application is independent of the other. Each application can consume the services exposed by other applications and also provide services externally.

Now that we have a simple understanding of the architecture, let’s look at how to code the implementation.

Implementation based on Dubbo

Dubbo should be the most used distributed service framework in China, based on this to achieve the new entry students should be very helpful.

Zookeeper, a registered center for installing Dubbo services, is available in the official documentation.

External provision of services

The first step is to define an interface in the SSM-API module, which is a user query interface

/** * Function: user API *@authorChenjiec * Date: 2017/4/4 9:46 PM *@sinceJDK 1.7 * /
public interface UserInfoApi {

    /** * Get user information *@param userId
     * @return
     * @throws Exception
     */
    public UserInfoRsp getUserInfo(int userId) throws Exception;
}Copy the code

Then implement it in the SSM-service module:

import com.alibaba.dubbo.config.annotation.Service;
/**
 * Function:
 * @authorChenjiec * Date: 2017/4/4 9:51 PM *@sinceJDK 1.7 * /
@Service
public class UserInfoApiImpl implements UserInfoApi {
    private static Logger logger = LoggerFactory.getLogger(UserInfoApiImpl.class);

    @Autowired
    private T_userService t_userService ;

    /** * Get user information **@param userId
     * @return
     * @throws Exception
     */
    @Override
    public UserInfoRsp getUserInfo(int userId) throws Exception {
        logger.info("User query Id="+userId);

        // Return the object
        UserInfoRsp userInfoRsp = new UserInfoRsp() ;
        T_user t_user = t_userService.selectByPrimaryKey(userId) ;

        / / build
        buildUserInfoRsp(userInfoRsp,t_user) ;

        return userInfoRsp;
    }


    /** * Build returns *@param userInfoRsp
     * @param t_user
     */
    private void buildUserInfoRsp(UserInfoRsp userInfoRsp, T_user t_user) {
        if (t_user ==  null){
            t_user = newT_user() ; } CommonUtil.setLogValueModelToModel(t_user,userInfoRsp); }}Copy the code

This is all generic code, but one thing worth noting is the @Service annotation provided by the Dubbo framework used here. The effect is to declare the service interface that needs to be exposed.

After that, there are several Dubbo related profiles.

spring-dubbo-config.xml

    <dubbo:application name="ssm-service" owner="crossoverJie"
        organization="ssm-crossoverJie" logger="slf4j"/>

    <dubbo:registry id="dubbo-registry" address=Zookeeper: / / 192.168.0.188: "2181"
        file="/tmp/dubbo.cachr" />

    <dubbo:monitor protocol="registry" />

    <dubbo:protocol name="dubbo" port="20880" />

    <dubbo:provider timeout="15000" retries="0" delay="1" />

    <dubbo:consumer check="false" timeout="15000" />Copy the code

In fact, it is to configure the ZK address registered by our service, as well as the service name, timeout time and other configurations.

spring-dubbo-provider.xml

<dubbo:annotation package="com.crossoverJie.api.impl" />Copy the code

This configuration scans the location of the annotation package, usually configured to the interface implementation package.

spring-dubbo-consumer.xml

This is a consumer profile that indicates the other applications we need to rely on. Here we configure in the SSM-boot project:

<dubbo:reference id="userInfoApi"
        interface="com.crossoverJie.api.UserInfoApi" />Copy the code

We directly configure the interface for user query we provided just now, so that when our own internal projects need to use this service, we only need to rely on SSM-Boot, and do not need to configure consumer separately. I also mentioned this in my last post on the Maven structure of THE SSM(X) Project Refactoring – Internet Project.

Installing the Administrative Console

Another thing you need to do is set up the admin console, where you can see how many services we have, how they are called, and so on.

Here we can download the official dubbo source code, package the dubbo-admin module, and put the generated WAR package into Tomcat to run.

However, it is important to note that you need to change the ZK address of dubo. properties to your own.

Dubbo. Registry. Address = zookeeper: / / 127.0.0.1:2181 dubbo. Admin. Root. The password = root dubbo. Admin. Guest. Password = guestCopy the code

Log in using root and password root. Use guest, and the password is guest.

The login interface is as follows:

[email protected]

We can see that there are two services registered, but no consumers.

Consumer services

In order to experience the consumption service more directly, I created a new project: github.com/crossoverJi… .

I also defined an interface in the SSM-consumer-API:

/** * Function: salary API *@authorChenjiec * Date: 2017/4/4 9:46 PM *@sinceJDK 1.7 * /
public interface SalaryInfoApi {

    /** * Get salary *@param userId
     * @return
     * @throws Exception
     */
    public SalaryInfoRsp getSalaryInfo(int userId) throws Exception;
}Copy the code

Because as consumers we are also providing a service to get paid.

Implemented in sSM-consumer-Service module:

/**
 * Function:
 * @authorChenjiec * Date: 2017/4/4 9:51 PM *@sinceJDK 1.7 * /
@Service
public class SalaryInfoApiImpl implements SalaryInfoApi {
    private static Logger logger = LoggerFactory.getLogger(SalaryInfoApiImpl.class);

    @Autowired
    UserInfoApi userInfoApi ;

    /** * Get user information **@param userId
     * @return
     * @throws Exception
     */
    @Override
    public SalaryInfoRsp getSalaryInfo(int userId) throws Exception {
        logger.info("Salary query Id="+userId);

        // Return the object
        SalaryInfoRsp salaryInfoRsp = new SalaryInfoRsp() ;

        // Invoke the remote service
        UserInfoRsp userInfo = userInfoApi.getUserInfo(userId);

        salaryInfoRsp.setUsername(userInfo.getUserName());

        returnsalaryInfoRsp; }}Copy the code

Where you can invoke the previous personal information service directly using the userInfoApi.

Note that we only need to rely on the SSM-boot module to make the call, because the SSM-boot module has already configured operations like consumer for us:

        <dependency>
            <groupId>com.crossoverJie</groupId>
            <artifactId>SSM-BOOT</artifactId>
        </dependency>Copy the code

It is also important to configure the spring-dubo-cosumer. XML configuration file in SSM-boot in the same path as we initialized the spring configuration file:

[email protected]

    <! -- Spring and Mybatis configuration files -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/*.xml</param-value>
    </context-param>Copy the code

Let’s run a single test to see if it works:

/**
 * Function:
 *
 * @authorChenjiec * Date: 2017/4/5 10:41 PM *@sinceJDK 1.7 * /
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:/spring/*.xml" })
public class SalaryInfoApiImplTest {

    @Autowired
    private SalaryInfoApi salaryInfoApi ;

    @Test
    public void getSalaryInfo(a) throws Exception {
        SalaryInfoRsp salaryInfo = salaryInfoApi.getSalaryInfo(1); System.out.println(JSON.toJSONString(salaryInfo)); }}Copy the code

Consumers. JPG


Provider. JPG





Let’s start the consumer project at the same time to see what happens to the administrative console:

[email protected]



com.crossoverjie.consumer.api.SalaryInfoApi



com.crossoverJie.api.UserInfoApi

[email protected]


conclusion

Such a distributed service based on Dubbo is enough. In actual development, we will develop a sub-application in a large system, so that if a sub-application fails, the whole project will not be affected.

One more point: in the actual production environment, we usually have a master and slave service for the same service, so that the whole application will not be unusable during the online process.

Speaking of the benefits of SOA, there are naturally some disadvantages to traditional patterns:

  • Breaking up a large project into hundreds or thousands of sub-applications is not possible manually, i.e. requires automated deployment rollout, such asJenkins.
  • Another thing that needs to be done is monitoring. A separate monitoring platform is needed to help us check the running status of each service in real time so as to locate and solve problems in time.
  • Log view analysis. After splitting logs, it is impossible to view logs on each server. A separate log view analysis tool is requiredelk.

The above is my understanding, if there is any mistake welcome to correct.

Project address: github.com/crossoverJi…

Personal blog address: Crossoverjie.top

GitHub address: github.com/crossoverJi… .