今天继续Windows10系统下用idea工具创建maven多模块管理的dubbo(dubbox)+zookeeper中间件分布式架构SSM项目环境搭建,provider的开发。
1. 新建一个module smbms-user-provider
2. 增加jar包依赖
----------------------------------以下是dubbo------------------------------------------
1)zookeeper jar包 (中间件的)
和注册中心通信的公共基础包。
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
2)zkclient jar包 (中间件的)
和注册中心通信的客户端包。
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.8</version>
</dependency>
3)dubbo jar包
dubbo 发布服务与订阅服务的包。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
4)smbms-common 公共包
公共的实体类与service接口。
<dependency>
<groupId>cn.kgc1803</groupId>
<artifactId>smbms-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
5)hessian jar包
hesian 提供中间通信协议(http ,dubbo等协议)
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.7</version>
</dependency>
--------------------------dubbox 的 jar 依赖------------------------------
6)json 插件 jar包 在smbms-common模块pom.xml引入
<!-- json 插件 -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
该插件的作用是在实体类上增加了@JsonProperty注解标签的属性会自动转化为json对象属性。
示例:
@JsonProperty
private Integer id;
按照这种方式,我们对smbms-common模块的order类进行了改造改造后需要再次打包发布,直接覆盖原来的文件,如下:
package cn.kgc1803.smbms_common.pojo;
import org.codehaus.jackson.annotate.JsonProperty;
import java.io.Serializable;
public class Order implements Serializable {
//@JsonProperty实体类可以自动转化为 json 类对象数据的属性
@JsonProperty
private Integer id;
@JsonProperty
private Integer ownerUserId;
@JsonProperty
private String productName;
@JsonProperty
private Double price;
@JsonProperty
private Integer amount;
public Order(){
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getOwnerUserId() {
return ownerUserId;
}
public void setOwnerUserId(Integer ownerUserId) {
this.ownerUserId = ownerUserId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
}
7)rest 风格访问dubbo(dubbox) 在smbms-user-provider模块pom.xml引入
<!--dubbox rest 风格包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
<version>2.8.4</version>
</dependency>
3. 编写smbms-user-provider模块的service
配置 dubbox rest 风格的访问配置:
//@Produces设置输出结果集的数据类型
@Path("/order")
@Produces(ContentType.APPLICATION_JSON_UTF_8)
public class OrderServiceImpl implements OrderService {
//@Path访问路径
@Path("/orderliset.html")
//@GET请求方式
@GET
public List<Order> findList() {
以上代码块中的方法:public List<Order> findList() 在实际开发中会带上参数,因此,为了灵活运用,方法上的@path后面应该灵活设置成从参数中获取的参数字段,例如后续贴出相应的改进后的代码。并且这两种方式在启动dubbox测试的时候会有细微区别如下面第7)步操作。 改进后的OrderServiceImpl类:
package cn.kgc1803.smbms_user_provider.service;
import cn.kgc1803.smbms_common.pojo.Order;
import cn.kgc1803.smbms_common.service.OrderService;
import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import java.util.ArrayList;
import java.util.List;
//@Produces设置输出结果集的 数据类型
@Path("/order")
@Produces(ContentType.APPLICATION_JSON_UTF_8)
public class OrderServiceImpl implements OrderService {
//@Path访问路径
//@GET请求方式
@Path("/orderlist/{userId}")
@GET
public List<Order> findList(@PathParam("userId") Integer userId) {
List<Order> orders = new ArrayList<Order>();
Order o = new Order();
o.setId(userId);
o.setOwnerUserId(11);
o.setAmount(33);
o.setPrice(55.3);
o.setProductName("华为p8");
orders.add(o);
return orders;
}
}
4. 配置dubbo 发布到服务(spring)
用idea工具新建spring 配置文件 dubbo_user_provider.xml,如下方式:
1)在配置文件中增加命名空间dubbo
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
2)注入service 配置到spring中
<!--service 注入-->
<bean id="userService" class="cn.kgc1803.smbms_user_provider.service.UserServiceImpl"/>
<bean id="orderService" class="cn.kgc1803.smbms_user_provider.service.OrderServiceImpl"/>
3)利用dubbo 命名空间配置应用名称(name:应用名称;owner:拥有者;organization:组织)
<!-- 设置提供者本次发布的应用名称-->
<dubbo:application name="user_provider_app" owner="kgc" organization="kgc1803"/>
4)配置注册中心的地址
<!-- 配置注册中心地址-->
<dubbo:registry address="zookeeper://localhost:2181"/>
5)声明一个发布协议(选择自己的协议风格 dubbo或者rest;rest风格有端口号)
<!-- 配置一个协议(dubbo协议) -->
<dubbo:protocol name="dubbo" contextpath="dubbo" />
<!--rest 协议 -->
<dubbo:protocol name="rest" port="20888"/>
6)发布服务----》两种风格(通过第5步定义的协议):protocol:协议风格;interface:对应的接口;ref:对象,即第1)步service对应的 id 。
<!-- dubbo方式发布服务 -->
<dubbo:service protocol="dubbo" interface="cn.kgc1803.smbms_common.service.UserService" ref="userService" />
<!-- rest 协议发布风格 -->
<dubbo:service protocol="rest" interface="cn.kgc1803.smbms_common.service.OrderService" ref="orderService"/>
7)编写测试类TestProvider,加载spring配置文件,页面启动bubbox测试:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestProvider {
public static void main(String[] args){
//加载spring配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo_user_provider.xml");
try {
//线程休眠10分钟,保证测试启动后,dubbo服务可使用的时间
Thread.sleep(10*60*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
8)为了启动测试类能更好的在控制台显示日志效果,方便我们对项目的报错进行查看和修改,这里我添加了一个配置文件,不需要你写,只需要在之前解压的zookeeper包里面找到,并复制到smbms-user-provider模块的resource下即可:
log4j.properties配置文件:
# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=.
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=DEBUG
zookeeper.tracelog.dir=.
zookeeper.tracelog.file=zookeeper_trace.log
#
# ZooKeeper Logging Configuration
#
# Format is "<default threshold> (, <appender>)+
# DEFAULT: console appender only
log4j.rootLogger=${zookeeper.root.logger}
# Example with rolling log file
#log4j.rootLogger=DEBUG, CONSOLE, ROLLINGFILE
# Example with rolling log file and tracing
#log4j.rootLogger=TRACE, CONSOLE, ROLLINGFILE, TRACEFILE
#
# Log INFO level and above messages to the console
#
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
#
# Add ROLLINGFILE to rootLogger to get log file output
# Log DEBUG level and above messages to a log file
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
# Max log file size of 10MB
log4j.appender.ROLLINGFILE.MaxFileSize=10MB
# uncomment the next line to limit number of backup files
#log4j.appender.ROLLINGFILE.MaxBackupIndex=10
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
#
# Add TRACEFILE to rootLogger to get log file output
# Log DEBUG level and above messages to a log file
log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
log4j.appender.TRACEFILE.Threshold=TRACE
log4j.appender.TRACEFILE.File=${zookeeper.tracelog.dir}/${zookeeper.tracelog.file}
log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
### Notice we are including log4j's NDC here (%x)
log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n
9)同样启动:http://localhost:8080/dubbo-admin-2.8.4/ 网址,查看首页是否有发布的监控中心:
列表详细信息:
10)启动测试(启动上面第7)步的测试即可进入网页查看服务是否发布成功)
dubbox测试:http://localhost:20888/order/orderlist.html (这种方式,每个系统都可以访问;这里的20888端口号是第5步的rest协议端口,order和orderlist.html是提供者实现类头部的注解路径,相当于controller的方式。)或者是带参数的方式(即service类对应的@path路径):http://localhost:20888/order/orderlist/{userId}
测试通过,证明之前写的OrderServiceImpl实现类的findList方法已通在smbms-common模块引入json 插件(依赖架包),并在Order实体类属性字段上增加的@JsonProperty注解标签会自动转化为json对象属性显示在前端页面上。这样也好为后面页面用Ajax请求后端数据做铺垫。
今天的任务就到此吧,有点疲惫了,还要继续补充知识,后面再接着更新!