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
At this point all the business logic can be satisfied in one project.
Vertical split – multiple applications
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.
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:
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:
<! -- 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
Let’s start the consumer project at the same time to see what happens to the administrative console:
com.crossoverjie.consumer.api.SalaryInfoApi
com.crossoverJie.api.UserInfoApi
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 as
Jenkins
. - 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 required
elk
.
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… .