springboot+dubbo+myBatis实现微服务集成

#springboot+dubbo+myBatis实现微服务集成

  • 代码下载:https://download.csdn.net/download/typ1805/10485048
  • 微服务架构成了当下的技术热点,实现微服务是要付出很大成本的,但也许是因为微服务的优点太过于吸引人,以至于大部分开发者都将它当成未来的发展趋势。

微服务架构的演进过程

  • dubbo的用户手册中介绍了服务化架构的进化过程,如下图:
    springboot+dubbo+myBatis实现微服务集成_第1张图片

微服务的技术关注点

  • 要实现一个微服务的架构,我们需要关注的技术点包括:服务注册、发现、负载均衡和健康检查,前端路由(网关),容错,服务框架的选择,动态配置管理等模块。这些模块可以组成一个简化的微服务架构图如下:
    springboot+dubbo+myBatis实现微服务集成_第2张图片

使用dubbo+zookeeper实现简化的微服务架构

  • 第一步:zookeeper集群的部署
    : 使用zookeeper作为dubbo的注册中心,部署起来并不麻烦。为了保持注册中心的高可用性,在生产环境下我们需要配置多个zookeeper协同运行。在集群模式下,zookeeper会基于Paxos算法从集群中选择一台作为leader,其他机器作为follower,注册中心的数据都以leader为准。一台zk机器成为leader的条件是超过这台机器是可用的,且被超过半数的机器选举为leader。基于这种实现方式,我们选择zk集群的数量时最好为奇数个,最少为3个,这样只要有超过半数的zk机器存活那注册中心就是可用的。

注:如果我们选择2台机器作为zk的集群,那只要有一台zk挂掉,另一台机器就无法得到超过半数的选票,那么这个zk集群就直接失效了。因此选2台机器作为zk集群的稳定性在理论上不如一台机器作为注册中心的稳定性。

: 以3台机器作为zk集群为例,每台zk的具体部署方式为:
1、下载安装包并解压到安装目录,zookeeper安装包的下载地址为:http://www.apache.org/dist/zookeeper/
2、进入解压目录的conf文件夹,配置zookeeper启动的基本参数。
在conf文件夹下有一个 zoo_sample.cfg的文件,是zk启动的配置样例,zookeeper进程在启动的时候会找zoo.cfg文件作为默认的配置文件,所以我们复制一个名称为zoo.cfg的文件,并编辑其中的配置信息如下:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=D:/zookeeper-3.4.12/data
dataLogDir=D:/zookeeper-3.4.12/logs
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

# zookeeper集群的部署
# server.A=B:C:D
#  A为数字,标识这条配置为第几个zk服务器,即机器id
#  B为host名,标识这个服务器的主机地址
#  C和D为zk集群的成员用于选举leader时的通讯端口
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

运行zookeeper进程,在zookeeper目录下的bin文件夹中,运行

        ./zkServer.sh start
        ps: 停止方法——运行 ./zkServer.sh stop
  • 第二步:开发前端服务和后端通用服务,maven模块结构,如图:
    springboot+dubbo+myBatis实现微服务集成_第3张图片

springboot-dubbo-parent的pom.xml文件:



	4.0.0

	com.example
	springboot-dubbo-parent
	0.0.1-SNAPSHOT
	pom

	springboot-dubbo-parent
	Demo project for Spring Boot

	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.9.RELEASE
		 
	

	
		springboot-dubbo-server
		springboot-dubbo-client
	
	
		UTF-8
		UTF-8
		1.8

		
		2.5.3
		3.4.5
		0.1
	

	   
		
			
			
			

			
				org.springframework.boot
				spring-boot-starter-web
				1.5.9.RELEASE
			

			
			
				com.alibaba
				dubbo
				${dubbo.version}
				
					
						org.springframework
						spring
					
				
			

			
				org.apache.zookeeper
				zookeeper
				${zk.version}
				
					
						org.slf4j
						slf4j-log4j12
					
					
						log4j
						log4j
					
				
			
			
				com.github.sgroschupf
				zkclient
				${zkclient.version}
			
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

springboot-dubbo-server的pom.xml文件:



	4.0.0

	com.example
	springboot-dubbo-server
	0.0.1-SNAPSHOT
	pom

	springboot-dubbo-server
	Demo project for Spring Boot

	
		com.example
		springboot-dubbo-parent
		0.0.1-SNAPSHOT
	
	
		springboot-dubbo-api
		springboot-dubbo-provider
	


springboot-dubbo-provider的pom.xml文件:



	4.0.0

	com.example.demo.provider
	apringboot-dubbo-provider
	0.0.1-SNAPSHOT
	jar

	apringboot-dubbo-provider
	Demo project for Spring Boot

	
		com.example
		springboot-dubbo-server
		0.0.1-SNAPSHOT
	

	
	

	
		
			org.springframework.boot
			spring-boot-starter
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		

		
		
			com.alibaba
			dubbo
		
		
			org.apache.zookeeper
			zookeeper
		
		
			com.github.sgroschupf
			zkclient
		

		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			1.3.1
		
		
			mysql
			mysql-connector-java
			runtime
		
		
			org.springframework.boot
			spring-boot-starter-jdbc
		

		
			com.example.admo.api
			springboot-dubbo-api
			0.0.1-SNAPSHOT
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	




dubbo配置文件provider.xml:




    
    

    
    

    
    


    
    
    

    
    

    
    
    
    
    


mysql数据库配置文件application.properties:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-active=10
spring.datasource.max-idle=5
spring.datasource.min-idle=0

服务层接口实现类 UserServiceImpl.java文件:

package com.example.demo.provider.api.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.example.demo.api.model.User;
import com.example.demo.api.service.UserService;
import com.example.demo.provider.dao.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 路径:com.example.demo.api.impl
 * 类名:
 * 功能:
 * 备注:该Service注解是dubbo的注解,不是spring的。若使用xml配置方式暴露接口,则不需要该注解。
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User findOneById(Integer id) {
       
        return userMapper.findOneById(id);
    }

}

dao层接口Usermapper.java文件:

package com.example.demo.provider.dao;


import com.example.demo.api.model.User;

/**
 * 路径:com.example.demo.dao
 * 类名:
 * 功能:《用一句话描述一下》
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
public interface UserMapper {

    User findOneById(Integer id);
}

myBatis的XML文件:






    


启动类ApringbootDubboProviderApplication.java文件:

package com.example.demo.provider;

import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * 路径:com.example.demo.provider
 * 类名:
 * 功能:《用一句话描述一下》
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
@SpringBootApplication
@MapperScan("com.example.demo.provider.dao")
@ImportResource("classpath:provider.xml")
public class ApringbootDubboProviderApplication {

	@Bean
	@ConfigurationProperties(prefix="spring.datasource")
	public DataSource dataSource() {
		return new org.apache.tomcat.jdbc.pool.DataSource();
	}

	@Bean
	public SqlSessionFactory sqlSessionFactoryBean() throws Exception {

		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource());

		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

		sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));

		return sqlSessionFactoryBean.getObject();
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dataSource());
	}

	public static void main(String[] args) throws InterruptedException {
		SpringApplication.run(ApringbootDubboProviderApplication.class, args);
		//pom中没有加spring-boot-starter-web依赖,启动时没有tomcat容器,会自动退出,所以加了一个sleep防止自动退出
		Thread.sleep(Long.MAX_VALUE);
	}
}

springboot-dubbo-api的pom.xml文件:



	4.0.0

	com.example.admo.api
	springboot-dubbo-api
	0.0.1-SNAPSHOT
	jar

	springboot-dubbo-api
	Demo project for Spring Boot

	
		com.example
		springboot-dubbo-server
		0.0.1-SNAPSHOT
	

	
		UTF-8
		UTF-8
		1.8
	

	
		
			org.springframework.boot
			spring-boot-starter
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		

	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	




api服务接口UserService.java文件:

package com.example.demo.api.service;


import com.example.demo.api.model.User;

/**
 * 路径:com.example.demo.api.service
 * 类名:
 * 功能:
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
public interface UserService {


    User findOneById(Integer id);

}

实体类User.java文件:

package com.example.demo.api.model;

import java.io.Serializable;

/**
 * 路径:com.example.demo.api.model
 * 类名:
 * 功能:《用一句话描述一下》
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
public class User implements Serializable {
    private Integer id;
    private String user_name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }
}

springboot-dubbo-client的pom.xml文件:



	4.0.0

	com.example
	springboot-dubbo-client
	0.0.1-SNAPSHOT
	jar

	springboot-dubbo-client
	Demo project for Spring Boot

	
		com.example
		springboot-dubbo-parent
		0.0.1-SNAPSHOT
	

	
	

	
		
			org.springframework.boot
			spring-boot-starter
		

		
			org.springframework.boot
			spring-boot-starter-test
			test
		

		
			org.springframework.boot
			spring-boot-starter-web
		

		
		
			com.alibaba
			dubbo
		
		
			org.apache.zookeeper
			zookeeper
		
		
			com.github.sgroschupf
			zkclient
		

		
			com.example.admo.api
			springboot-dubbo-api
			0.0.1-SNAPSHOT
		

	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	




dubbo配置文件consumer.xml:




    
    

    
    

    
    

    
    

    
    
    

UserController.java文件:

package com.example.demo.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.example.demo.api.model.User;
import com.example.demo.api.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * 路径:com.example.demo.controller
 * 类名:
 * 功能:《用一句话描述一下》
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * 注入服务提供方暴露的接口,通过@Reference注解,dubbo会在扫描的时候自动代理接口,然后通过rpc调用远程服务。
     * 如果用xml配置方式,需要将@Reference换成@Autowired。
     */
    @Reference
    UserService userService;

    @RequestMapping("/find")
    @ResponseBody
    public User findOneById(Integer id){
        System.out.println("------Controller--------id------"+id);
        User user = userService.findOneById(id);
        if(user == null){
            user = new User();
        }
        return user;
    }

}

启动类 SpringbootDubboClientApplication.java文件:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;


/**
 * 路径:com.example.demo
 * 类名:
 * 功能:《用一句话描述一下》
 * 备注:
 * 创建人:
 * 创建时间:
 * 修改人:
 * 修改备注:
 * 修改时间:
 */
@SpringBootApplication
@ImportResource("classpath:consumer.xml")
public class SpringbootDubboClientApplication {

    public static void main(String[] args) throws Exception{
        SpringApplication.run(SpringbootDubboClientApplication.class, args);
    }
}

启动成功,如图:
springboot+dubbo+myBatis实现微服务集成_第4张图片
springboot+dubbo+myBatis实现微服务集成_第5张图片

浏览器访问,如图:
springboot+dubbo+myBatis实现微服务集成_第6张图片

注意(远程调用失败问题):

Caused by: com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method subscribe in the service com.alibab

a.dubbo.registry.RegistryService. Tried 3 times of the providers[172.168.1.167:2181] (1/1) from the registry

172.168.1.167:2181 on the consumer 169.254.249.102 using the dubbo version2.4.9. Last error is: Invoke remote

method timeout.

解决方法一:

这个是由于dubbo接口中的的传输对象没有被序列化而导致的,只需要要检查dubbo接口中参数中的实体类实现序列化(implementsSerializable)就可以解决这一个异常.

解决方法二:

解决这个问题这个只需要重新暴露服务,在Zk上注册服务提供者信息即可。具体就是要排查服务提供者可能出现的问题,解决后部署并重启服务提供者即可。

解决方法三:

1.基本就是dubbo provider没有启动会造成这种情况。

2.api和service是同一个项目,并不是俩项目。

通过启动api,run on server是不能启动service的,必须通过config/startConfig.java,debug as java application启动。

3.启动思路总结:

1.api通过run on server启动

2.service通过startConfig.java启动。debug as java application

要想了解更多的信息可以通过官方文档进行学习:

dubbo中文文档:http://dubbo.io/
zookeeper文档:http://zookeeper.apache.org/

欢迎关注

springboot+dubbo+myBatis实现微服务集成_第7张图片

你可能感兴趣的:(springboot+dubbo+myBatis实现微服务集成)