结合了网上的两篇博客综合实现了一下整体的过程:
Dubbo为什么要与zookeeper/Consule一起使用?
dubbo主要是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的.告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册.
zookeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知道,简单来说就是ip地址和服务名称的对应关系。zookeeper通过心跳机制可以检测挂掉的机器并将挂掉机器的ip和服务对应关系从列表中删除。
看图识物:
上图所示,假如我有四台服务器,每台服务器都提供相同的服务,如果我消费者去掉用的时候,肯定要在四个当中选择某一个去调用,可是选择哪一个就是一个难题,当然这就涉及到负载均衡问题了,或者我们在消费者这边加代码逻辑判断达到负载均衡的效果。还有每次调用的时候都不知道要去掉哪个服务,都要查询当前有哪些服务提供者,这是很耗开销的,当服务提供越来越多的时候,越来越乱。
最终方案:
利用zookeeper生成的节点树,服务器提供者在启动的时候,将提供的服务名称和地址以节点的方式注册都服务器zookeeper服务器配置中心,消费者通过服务器配置中心获取需要的服务名称节点下的服务地址。因为znode有非持久节点的特性,服务器可以动态的从服务配置中心一处,并且触发消费者的watcher方法!!!
消费者只有在第一次调用的时候直接本地缓存服务器列表信息,而不需要重新发起请求到服务器配置中心区获取相应 的服务器列表,直到服务器地址列表有变化(机器下线或者上线),变更之后消费者watcher进行服务地址的重新查询。正是因为这种无中心化的结构,使得服务消费者在服务信息没变更时候,几乎不依赖配置中心,解决了负载均衡设备导致的单点故障的问题,大大减少了服务配置中心的压力
此处以windows环境下为例
注:linux安装参考http://blog.csdn.net/lk10207160511/article/details/50526404
在apache的官方网站提供了好多镜像下载地址,然后找到对应的版本,目前最新的是3.3.6
下载地址:
http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.3.6/zookeeper-3.3.6.tar.gz
把下载的zookeeper的文件解压到指定目录
修改conf下增加一个zoo.cfg
内容如下:
# The number of milliseconds of eachtick 心跳间隔毫秒每次
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 gettinganacknowledgement
syncLimit=5
# the directory where the snapshotisstored. //镜像数据位置
dataDir=D:\\data\\zookeeper
#日志位置
dataLogDir=D:\\logs\\zookeeper
# the port at which the clientswillconnect 客户端连接的端口
clientPort=2181
注:如果启动有报错提示cfg文件有错误,可以用zoo_sample.cfg内内容替代也是可以的
进入到bin目录,并且启动zkServer.cmd,这个脚本中会启动一个Java进程
这个时候zookeeper已经安装成功了.
下载dubbo-admin-2.4.1.war包,解压到tomcat中。
如图所示:
修改dubbo.properties文件,里面指向Zookeeper ,使用的是Zookeeper 的注册中心。
然后启动tomcat服务,用户名和密码:root,并访问服务,显示登陆页面,说明dubbo-admin部署成功,如图所示:
在把dubbo-admin.war部署到Tomcat中运行时,可能会存在jdk版本的问题 导致这个dubbo-admin的管理界面跑不起来
解决办法:下载dubbo-admin的源码 引入ide中 更改其中pom文件中的 一些相应的配置.https://blog.csdn.net/wangzi19933/article/details/54139246 这里面提供解决的办法
4个项目的依赖关系是:common里面暂时存放的只有user一个实体类,可以根据需求在里面加上其他的公共类,分页,验证等,这个项目不依赖其他的项目,其他3个项目都需要依赖它,所有这个项目需要先打包(相信做个maven项目的人应该都会-----如果对项目有所改动的话,需要先 maven clean,然后再maven install);
第二个需要打包的是 app项目,service和web项目都依赖它,然后再打包service项目,最后web项目。
xy-commer-common 项目目录:
User实体类具体代码:
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public long id;
public String uname;
public String pwd;
public long ctime;
public String phone;
public String info;
public String img;
//............
}
pom.xml配置 父级xy-commer
UTF-8
junit
junit
3.8.1
test
org.apache.commons
commons-lang3
3.5
com.google.code.gson
gson
com.atlassian.commonmark
commonmark
0.8.0
com.vdurmont
emoji-java
3.2.0
xy-commer-app 项目目录:
Userservice接口 具体代码:
import xy.commer.cloud.entity.User;
public interface UserService {
User findUserById(long id);
}
pom.xml
UTF-8
junit
junit
3.8.1
test
xy-commer-common
xy-commer-common
0.0.1-SNAPSHOT
xy-commer-service 项目目录:
ServiceMain springboot启动类
package xy.commer.cloud.main;
import java.io.IOException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
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.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.dubbo.config.annotation.Service;
/**
*
* service 服务 springboot 核心启动类
*
*/
@SpringBootApplication
@ComponentScan(basePackages = { "com.commer.app.service.impl" }, includeFilters = {
@Filter(classes = { Service.class }) })
@ImportResource(locations = { "classpath:dubboprovider.xml" })
@MapperScan("xy.commer.cloud.main.mapper")
public class ServiceMian {
@Bean(initMethod = "init", destroyMethod = "close")
//数据源以spring.datasource大头
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
//加载mybatis的映射文件
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:/mybatis-mapping/*Mapper.xml"));
return sqlSessionFactoryBean.getObject();
}
public static void main(String[] args) throws IOException {
SpringApplication.run(ServiceMian.class, args);
System.out.println("xy-commer-service-服务运行中...");
System.in.read();
}
}
UserMapper接口:
@Component
public interface UserMapper {
User findUserById(long id);
}
UserServiceImpl:
package xy.commer.cloud.main.service.impl;
import javax.annotation.Resource;
import com.alibaba.dubbo.config.annotation.Service;
import xy.commer.cloud.entity.User;
import xy.commer.cloud.main.mapper.UserMapper;
import xy.commer.cloud.service.UserService;
//因为作为一个dubbo服务提供者,启动时需要知道发布的服务是在哪,不使用dubbo提供的@service注解会出现问题的。
//注意这里是service要引dubbo的
@Service
public class UserServiceImpl implements UserService {
@Resource
UserMapper userMapper;
@Override
public User findUserById(long id) {
return this.userMapper.findUserById(id);
}
}
userMapper.xml
application.properti..
#pagehelper
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
# db config
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.initialSize=20
spring.datasource.minIdle=10
spring.datasource.maxActive=100
#port set
server.port=8012
dubbo.配置文件
pom.xml
UTF-8
com.alibaba
dubbo
2.5.3
org.springframework
spring
org.apache.zookeeper
zookeeper
3.4.6
org.slf4j
slf4j-log4j12
log4j
log4j
com.github.sgroschupf
zkclient
0.1
mysql
mysql-connector-java
com.alibaba
druid
1.0.18
org.wisdom-framework
mysql-connector-java
5.1.34_1
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
org.springframework.boot
spring-boot-configuration-processor
true
xy-commer-common
xy-commer-common
0.0.1-SNAPSHOT
xy-commer-app
xy-commer-app
0.0.1-SNAPSHOT
然后 启动ServiceMain启动测试一下如果出现以下 说明成功了一小步:
然后是xy-commer-web的 目录结构:
CusrMain:
package xy.commer.cloud.main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
import xy.commer.cloud.entity.User;
import xy.commer.cloud.service.UserService;
@SpringBootApplication
@ImportResource(locations = { "classpath:dubbo-consumer.xml" })
public class CustMain {
public static void main(String[] args) {
ApplicationContext tc = SpringApplication.run(CustMain.class, args);
UserService userService = (UserService) tc.getBean("userService");
User user = userService.findUserById(1l);
System.err.println(user.toString());
}
}
application.proper..
#port set
server.port=8011
dubbo.配置文件
我觉得 web 服务发现者这边 就列这些就够了 其他的按照个人的业务需求而添加了,然后运行springboot的启动类看结果:前提是服务提供者那边 得先启动:如果直接启动web发现者端 会报错Caused by: java.lang.IllegalStateException: Failed to check the status of the service xy.commer.cloud.service.UserService. No provider available for the service xy.commer.cloud.service.UserService 没有找到服务的提供者
最后附上源码下载地址:https://download.csdn.net/download/wangbo54979/10338460