下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper
下载完成之后,解压,进入到”conf”目录下,新建一个”zoo.cfg”
内容如下:
tickTime=2000
dataDir= /Users/chenqimiao/zookeeper-3.4.8/data
dataLogDir=/Users/chenqimiao/zookeeper-3.4.8/logs
clientPort=2181
参数说明:
#tickTime: zookeeper中使用的基本时间单位, 毫秒值.
#dataDir: 数据目录. 可以是任意目录.
#dataLogDir: log目录, 同样可以是任意目录. 如果没有设置该参数, 将使用和#dataDir相同的设置.
#clientPort: 监听client连接的端口号.
执行
以上介绍的就是zookeeper的单机模式。当然还有伪分布式和分布式的部署方式,这里就不再阐述,有兴趣的可以自行百度。
更新下链接,不知道是不是这个项目合入Apache的缘故,链接都变成了https://github.com/apache/incubator-dubbo/
按照常理,直接去
https://github.com/alibaba/dubbo(https://github.com/apache/incubator-dubbo)
下载,然后进入下面的dubbo-admin目录,进行mvn打包即可,但是不知道为何,却找不到dubbo-admin这个目录。那就直接去下载他们打包好的源代码吧:https://github.com/alibaba/dubbo/releases(https://github.com/apache/incubator-dubbo/releases)
方法1、解压后,根目录里存在dubbo-admin,进入 mvn package -Dmaven.test.skip=true
安装完后,生成target目录,进入这个目录,找到dubbo-admin-2.6.0这个目录,把这个目录全部copy到tomcat的目录webapps下的ROOT下面(删除tomcatwebapps目录下ROOT原有内容)
方法2、解压后,根目录里存在dubbo-admin,进入 mvn install -Dmaven.test.skip=true
安装完后,生成target目录,进入这个目录,找到dubbo-admin-2.6.0.war,把这个war包copy到tomcat的目录webapps下的ROOT下面(删除tomcat webapps目录下ROOT原有内容),然后使用jar xvf dubbo-admin-2.6.0.war解压war包,把解压后的内容全部放到ROOT目录下
启动tomcat,就可以看到dubbo-admin的界面,默认帐号密码root/root
启动tomcat方法:进入目录/home/admin/apache-tomcat-8.5.24/bin,然后 sh startup.sh
在目录/home/admin/apache-tomcat-8.5.24/webapps/ROOT/WEB-INF下的配置dubbo.properties,可以修改帐号密码,以及注册信息
一路next完成之后,在pom中加入如下依赖(dubbo和zookeeper)
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.4.10version>
<exclusions>
<exclusion>
<artifactId>springartifactId>
<groupId>org.springframeworkgroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.4.6version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12artifactId>
<groupId>org.slf4jgroupId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>com.github.sgroschupfgroupId>
<artifactId>zkclientartifactId>
<version>0.1version>
dependency>
此处需要修改pom.xml的一个设置 ,下文加黑部分,这样maven install的包被引用后才可用
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<skip>trueskip>
configuration>
plugin>
plugins>
build>
生产者的包配置如下,记住这个配置 ,一会再消费者处会用到
<groupId>com.dubbogroupId>
<artifactId>serverartifactId>
<version>0.0.1version>
<packaging>jarpackaging>
接下来先构建一个生产者
来一个测试接口:
package com.dubbo.server.service;
/**
* @author Mr.C
* @Description
* @create 2018/7/16 17:43
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public interface TestService {
String sayHello(String name);
}
来一个实现类
package com.dubbo.server.service.impl;
import com.dubbo.server.service.TestService;
/**
* @author Mr.C
* @Description
* @create 2018/7/16 17:44
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class TestServiceImpl implements TestService {
@Override
public String sayHello(String name) {
return "Hello " + name + "!";
}
}
在resource下面加入一个providers.xml,添加如下配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-provider" owner="dubbo-provider"/>
<dubbo:registry address="zookeeper://172.30.160.66:2181" check="false" subscribe="false"/>
<dubbo:service interface="com.dubbo.server.service.TestService" ref="testService"/>
<bean id="testService" class="com.dubbo.server.service.impl.TestServiceImpl">bean>
启动类:
package com.dubbo.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource(value = {"classpath:providers.xml"})
public class SpringbootDubboServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDubboServerApplication.class, args);
}
}
在application.properties中加入启动端口:
server.port=8011
启动这个项目,就可以在dubbo-admin中看到这个服务了
如生产者一样新建一个springboot项目,在pom.xml中引入生产者的包,如下
<dependency>
<groupId>com.dubbogroupId>
<artifactId>serverartifactId>
<version>0.0.1version>
dependency>
在resource下加入consumer.xml,配置如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-consumer"/>
<dubbo:registry check="false" address="zookeeper://172.30.160.66:2181"/>
<dubbo:reference interface="com.dubbo.server.service.TestService" id="testService"/>
beans>
配置启动类
package com.dubbo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
/**
* @author Mr.c
*/
@SpringBootApplication
@ImportResource(value = {"classpath:consumer.xml"})
public class SpringbootDubboConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDubboConsumerApplication.class, args);
}
}
来一个controller
package com.dubbo.consumer.controller;
import com.dubbo.server.service.TestService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @author Mr.C
* @Description
* @create 2018/7/16 17:57
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
@Controller
public class TestController {
@Resource
private TestService testService;
@RequestMapping(value = "/" ,produces = "application/json;charset=utf-8")
@ResponseBody
private String test(){
return testService.sayHello("chengwei");
}
}
启动之后,首先我们发现服务有了消费者
紧接着,我们用chrome请求restful接口,消费者服务通过RPC调用请求生产者提供的服务,经过两层服务调用返回后,chrome得到最终的response。
大致这样就完成了简单的分布式项目构建。
sheet0
sheet1
二者在10002 和10004中的年龄上做了区别,生产者读取sheet1 中的信息,消费者读取sheet0中的用户信息,我们最终将结果存放到sheet0中,预期结果为:true,false,true,false,true
在pom.xml中引入poi 的 包
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>3.14version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.14version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxml-schemasartifactId>
<version>3.14version>
dependency>
创建用户信息类,用于存放从excel中读取的用户信息
package com.dubbo.server.entity;
import java.io.Serializable;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 9:42
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class UserInfo implements Serializable {
private String id;
private String userId;
private String userName;
private String password;
private String sex;
private Integer age;
private Long phoneNo;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"id\":\"")
.append(id).append('\"');
sb.append(",\"userId\":\"")
.append(userId).append('\"');
sb.append(",\"userName\":\"")
.append(userName).append('\"');
sb.append(",\"password\":\"")
.append(password).append('\"');
sb.append(",\"sex\":")
.append(sex);
sb.append(",\"age\":")
.append(age);
sb.append(",\"phoneNo\":")
.append(phoneNo);
sb.append('}');
return sb.toString();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Long getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = phoneNo;
}
}
创建一个用户检查参数类 ,用于从消费者端发送到生产者端处理及返回最终结果
package com.dubbo.server.entity;
import java.io.Serializable;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 10:29
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class UserInfoVo implements Serializable{
private String id;
private String md5UserInfo;
private Boolean enableUser;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMd5UserInfo() {
return md5UserInfo;
}
public void setMd5UserInfo(String md5UserInfo) {
this.md5UserInfo = md5UserInfo;
}
public Boolean getEnableUser() {
return enableUser;
}
public void setEnableUser(Boolean enableUser) {
this.enableUser = enableUser;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"id\":\"")
.append(id).append('\"');
sb.append(",\"md5UserInfo\":\"")
.append(md5UserInfo).append('\"');
sb.append(",\"enableUser\":")
.append(enableUser);
sb.append('}');
return sb.toString();
}
}
创建三个工具类,分别是md5 加密,excel读取数字格式数据中的小数点处理,springboot的resource目录获取
package com.dubbo.server.utils;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 9:56
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class Md5Utils {
public static String encodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md5=MessageDigest.getInstance("MD5");
BASE64Encoder base64 = new BASE64Encoder();
String newStr = base64.encode(md5.digest(str.getBytes("UTF-8")));
return newStr;
}
}
package com.dubbo.server.utils;
import org.springframework.util.ResourceUtils;
import java.io.FileNotFoundException;
/**
* @author Mr.C
* @Description
* @create 2018/7/27 10:28
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class PathUtils {
public static String getResourcePath() throws FileNotFoundException {
return ResourceUtils.getURL("classpath:").getPath();
}
}
package com.dubbo.server.utils;
import org.apache.poi.xssf.usermodel.XSSFCell;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 20:12
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class PointUtils {
public static String delPoint(XSSFCell cell){
String cellValue=String.valueOf(cell);
if(cellValue.contains(".0")){
cellValue=cellValue.split("\\.")[0];
}
return cellValue;
}
}
接下来再resource目录下新建一个文件夹 calfile ,将userInfo.xlsx 复制到其中
新建一个登录检查类接口
package com.dubbo.server.service;
import com.dubbo.server.entity.UserInfoVo;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 10:26
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public interface CheckUserService {
UserInfoVo checkUser(UserInfoVo userInfoVo);
List checkUser(List userInfoVoList) throws IOException, NoSuchAlgorithmException;
}
新建一个登录检查接口实现类
package com.dubbo.server.service.impl;
import com.dubbo.server.entity.UserInfo;
import com.dubbo.server.entity.UserInfoVo;
import com.dubbo.server.service.CheckUserService;
import com.dubbo.server.utils.Md5Utils;
import com.dubbo.server.utils.PathUtils;
import com.dubbo.server.utils.PointUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
* @author Mr.C
* @Description
* @create 2018/7/26 10:28
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
public class CheckUserServiceImpl implements CheckUserService {
@Override
public UserInfoVo checkUser(UserInfoVo userInfoVo) {
return null;
}
@Override
public List checkUser(List userInfoVoList) throws IOException, NoSuchAlgorithmException {
//1、读取excel中的用户信息
FileInputStream in = new FileInputStream( PathUtils.getResourcePath().concat("calfile/userINfo.xlsx"));
XSSFWorkbook wb=new XSSFWorkbook(in);
XSSFSheet sheet = wb.getSheetAt(1);
int num=sheet.getLastRowNum();
for(int i=1;i<=num;i++){
UserInfo userInfo=new UserInfo();
XSSFRow row = sheet.getRow(i);
int index=0;
userInfo.setId(PointUtils.delPoint(row.getCell(index)));
userInfo.setUserId(PointUtils.delPoint(row.getCell(++index)));
userInfo.setUserName(PointUtils.delPoint(row.getCell(++index)));
userInfo.setPassword(PointUtils.delPoint(row.getCell(++index)));
userInfo.setSex(PointUtils.delPoint(row.getCell(++index)));
userInfo.setAge(Integer.valueOf(PointUtils.delPoint(row.getCell(++index))));
userInfo.setPhoneNo(Long.valueOf(PointUtils.delPoint(row.getCell(++index))));
//对用户进行验证
for(UserInfoVo userInfoVo:userInfoVoList){
if(userInfo.getId().equals(userInfoVo.getId())){
if(userInfoVo.getMd5UserInfo().equals(Md5Utils.encodeByMd5(userInfo.toString()))){
userInfoVo.setEnableUser(true);
}else{
userInfoVo.setEnableUser(false);
}
}
}
}
return userInfoVoList;
}
}
在provider.xml 中添加新增的服务,最终结果如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-provider" owner="dubbo-provider"/>
<dubbo:registry address="zookeeper://172.30.160.66:2181" check="false" subscribe="false"/>
<dubbo:service interface="com.dubbo.server.service.TestService" ref="testService"/>
**<dubbo:service interface="com.dubbo.server.service.CheckUserService" ref="checkUserService"/>**
<bean id="testService" class="com.dubbo.server.service.impl.TestServiceImpl">bean>
<bean id="checkUserService" class="com.dubbo.server.service.impl.CheckUserServiceImpl">bean>
beans>
使用maven install 重新打包生产者,然后更新消费者中的生产者的包,将用于检查用户信息的服务接入进来,修改后的配置如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-consumer"/>
<dubbo:registry check="false" address="zookeeper://172.30.160.66:2181"/>
<dubbo:reference interface="com.dubbo.server.service.TestService" id="testService"/>
<dubbo:reference interface="com.dubbo.server.service.CheckUserService" id="checkUserService" />
beans>
同样的在resource源文件下新建文件夹calfile 并将userInfo.xlsx拷贝进去
创建一个用户信息检测类 ,用来发送用户信息及结果存储UserLogin
package com.dubbo.consumer.controller;
import com.dubbo.server.entity.UserInfo;
import com.dubbo.server.entity.UserInfoVo;
import com.dubbo.server.service.CheckUserService;
import com.dubbo.server.utils.Md5Utils;
import com.dubbo.server.utils.PathUtils;
import com.dubbo.server.utils.PointUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Mr.C
* @Description 用于用户登录信息检测
* @create 2018/7/26 10:02
* Copyright: Copyright (c) 2018
* Company:CWWT
*/
@Controller
public class UserLogin {
@Resource
private CheckUserService checkUserService;
/**
* 读取excel文件中的用户信息,进行md5加密,并调用dubbo接口进行验证用户是否可用,将验证结果回传写入excel中
*/
@RequestMapping(value = "/checkUser" ,produces = "application/json;charset=utf-8")
@ResponseBody
private String checkUser() throws IOException, NoSuchAlgorithmException {
List infoVoList=new ArrayList<>();
//1、读取excel中的用户信息
FileInputStream in = new FileInputStream( PathUtils.getResourcePath().concat("calfile/userINfo.xlsx"));
XSSFWorkbook wb=new XSSFWorkbook(in);
XSSFSheet sheet = wb.getSheetAt(0);
int num=sheet.getLastRowNum();
int lastCellNum=0;
for(int i=1;i<=num;i++){
UserInfo userInfo=new UserInfo();
XSSFRow row = sheet.getRow(i);
int index=0;
userInfo.setId(PointUtils.delPoint(row.getCell(index)));
userInfo.setUserId(PointUtils.delPoint(row.getCell(++index)));
userInfo.setUserName(PointUtils.delPoint(row.getCell(++index)));
userInfo.setPassword(PointUtils.delPoint(row.getCell(++index)));
userInfo.setSex(PointUtils.delPoint(row.getCell(++index)));
userInfo.setAge(Integer.valueOf(PointUtils.delPoint(row.getCell(++index))));
userInfo.setPhoneNo(Long.valueOf(PointUtils.delPoint(row.getCell(++index))));
//计算出最后一列的位置
lastCellNum=index+1;
//2、将用户信息批量进行加密
UserInfoVo infoVo=new UserInfoVo();
infoVo.setId(userInfo.getId());
infoVo.setMd5UserInfo(Md5Utils.encodeByMd5(userInfo.toString()));
infoVoList.add(infoVo);
}
//3、调用dubbo接口,将结果返回
infoVoList=checkUserService.checkUser(infoVoList);
Map map=new HashMap<>(infoVoList.size());
for(UserInfoVo infoVo:infoVoList){
map.put(infoVo.getId(),infoVo.getEnableUser());
}
//4、将返回结果重新写入对应的excel列表中
XSSFRow row = sheet.getRow(0);
row.createCell(lastCellNum).setCellValue("结果");
for (int i=1;i<=num;i++){
row = sheet.getRow(i);
String id=PointUtils.delPoint(row.getCell(0));
String value=String.valueOf(map.get(id));
row.createCell(lastCellNum).setCellValue(value);
}
in.close();
OutputStream out = new FileOutputStream(PathUtils.getResourcePath().concat("calfile/userINfo.xlsx"));
wb.write(out);
out.close();
return "success";
}
}
在启动后 ,访问http://localhost:8012/checkUser 可以看到
然后打开消费者编译后文件夹下的userInfo.xml 打开查看结果
1、[email protected]:lcgk/springboot-dubbo-consumer.git
2、[email protected]:lcgk/springboot-dubbo-server.git