Merge branch 'dev' of github.com:nutzam/nutzboot into dev

This commit is contained in:
pangwu86 2019-03-28 20:31:31 +08:00
commit bc85aed144
53 changed files with 13353 additions and 10 deletions

View File

@ -210,8 +210,9 @@ public class MainLauncher {
- [x] [Shiro+LCache](https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-cache)基于shiro/jedis/插件的分布式可持久化的session缓存
- 分布式事务
- [x] [tcc-transaction](https://github.com/changmingxie/tcc-transaction/tree/dev-1.2.x)基于tcc-transaction的nutz容器支持
- [x] [fescar](https://github.com/alibaba/fescar) 阿里开源的分布式事务引擎
- 计划任务
- [x] **starter-[quartz](http://www.quartz-scheduler.org)**
- [x] **starter-[quartz](http://www.quartz-scheduler.org)** 大家都知道
- [x] starter-xxl-job [国产分布式任务调度平台](https://github.com/xuxueli/xxl-job/pull/253)
- [ ] starter-scheduledx 阿里云分布式任务
- 模板引擎

View File

@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar-account</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-fescar</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-nutz-dao</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-dubbo-alibaba</artifactId>
<version>${fescar.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,31 @@
package io.nutz.demo.dubbo.rpc;
import org.nutz.boot.NbApp;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import io.nutz.demo.bean.Account;
@IocBean(create="init")
public class DemoFescarAccountServiceLauncher {
@Inject
Dao dao;
public void init() {
dao.create(Account.class, false);
if (dao.count(Account.class, Cnd.where("userId", "=", "U100001")) == 0) {
Account account = new Account();
account.setUserId("U100001");
account.setMoney(1000);
dao.insert(account);
}
}
public static void main(String[] args) throws Exception {
new NbApp().run();
}
}

View File

@ -0,0 +1,34 @@
package io.nutz.demo.dubbo.rpc.service.impl;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fescar.core.context.RootContext;
import io.nutz.demo.bean.Account;
import io.nutz.demo.dubbo.rpc.service.AccountService;
@IocBean
@Service(interfaceClass=AccountService.class)
public class AccountServiceImpl implements AccountService {
private static final Log log = Logs.get();
@Inject
private Dao dao;
@Override
public void debit(String userId, int money) {
log.info("Account Service ... xid: " + RootContext.getXID());
log.infof("Deducting balance SQL: update account_tbl set money = money - %s where user_id = %s", money, userId);
dao.update(Account.class, Chain.makeSpecial("money", "-" + money), Cnd.where("userId", "=", userId));
log.info("Account Service End ... ");
}
}

View File

@ -0,0 +1,32 @@
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
#thread factory for netty
thread-factory {
boss-thread-prefix = "NettyBoss"
worker-thread-prefix = "NettyServerNIOWorker"
server-executor-thread-prefix = "NettyServerBizHandler"
share-boss-worker = false
client-selector-thread-prefix = "NettyClientSelector"
client-selector-thread-size = 1
client-worker-thread-prefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
boss-thread-size = 1
#auto default pin or 8
worker-thread-size = 8
}
}
service {
#vgroup->rgroup
vgroup_mapping.my_test_tx_group = "localRgroup"
#only support single node
localRgroup.grouplist = "127.0.0.1:8091"
#degrade current not support
enableDegrade = false
#disable
disable = false
}

View File

@ -0,0 +1,12 @@
server.port=0
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
jdbc.username=root
jdbc.password=root
fescar.applicationId=dubbo-fescar-account
fescar.txServiceGroup=my_test_tx_group
dubbo.application.name=dubbo-fescar-account
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false

View File

@ -0,0 +1,7 @@
log4j.rootLogger=debug,Console
log4j.logger.org.eclipse.jetty=info
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n

View File

@ -0,0 +1,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
<dependencies>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-dubbo</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,47 @@
package io.nutz.demo.bean;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Index;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.entity.annotation.TableIndexes;
@Table("account_tbl")
@TableIndexes(@Index(fields="userId", unique=true))
public class Account {
@Id
private long id;
@Column("user_id")
private String userId;
@Column
private int money;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}

View File

@ -0,0 +1,54 @@
package io.nutz.demo.bean;
import java.io.Serializable;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Table;
@Table("order_tbl")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private long id;
@Column("user_id")
private String userId;
@Column("commodity_code")
private String commodityCode;
@Column
private int count;
@Column
private int money;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getCommodityCode() {
return commodityCode;
}
public void setCommodityCode(String commodityCode) {
this.commodityCode = commodityCode;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}

View File

@ -0,0 +1,41 @@
package io.nutz.demo.bean;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Table;
@Table("storage_tbl")
public class Storage {
@Id
private long id;
@Column("commodity_code")
private String commodityCode;
@Column
private int count;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getCommodityCode() {
return commodityCode;
}
public void setCommodityCode(String commodityCode) {
this.commodityCode = commodityCode;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

View File

@ -0,0 +1,8 @@
package io.nutz.demo.dubbo.rpc.service;
public interface AccountService {
/**
* debit balance of user's account
*/
void debit(String userId, int money);
}

View File

@ -0,0 +1,6 @@
package io.nutz.demo.dubbo.rpc.service;
public interface BusinessService {
void purchase(String userId, String commodityCode, int orderCount, boolean dofail);
}

View File

@ -0,0 +1,11 @@
package io.nutz.demo.dubbo.rpc.service;
import io.nutz.demo.bean.Order;
public interface OrderService {
/**
* create order
*/
Order create(String userId, String commodityCode, int orderCount);
}

View File

@ -0,0 +1,8 @@
package io.nutz.demo.dubbo.rpc.service;
public interface StorageService {
/**
* deduct storage count
*/
void deduct(String commodityCode, int count);
}

View File

@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar-order</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-nutz-dao</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-fescar</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-dubbo-alibaba</artifactId>
<version>${fescar.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,23 @@
package io.nutz.demo.dubbo.rpc;
import org.nutz.boot.NbApp;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import io.nutz.demo.bean.Order;
@IocBean(create="init")
public class DemoFescarOrderServiceLauncher {
@Inject Dao dao;
public void init() {
dao.create(Order.class, false);
}
public static void main(String[] args) throws Exception {
new NbApp().run();
}
}

View File

@ -0,0 +1,44 @@
package io.nutz.demo.dubbo.rpc.service.impl;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import io.nutz.demo.bean.Order;
import io.nutz.demo.dubbo.rpc.service.AccountService;
import io.nutz.demo.dubbo.rpc.service.OrderService;
@IocBean
@Service(interfaceClass=OrderService.class)
public class OrderServiceImpl implements OrderService {
@Inject
private Dao dao;
@Inject
@Reference
private AccountService accountService;
public Order create(String userId, String commodityCode, int orderCount) {
int orderMoney = calculate(commodityCode, orderCount);
accountService.debit(userId, orderMoney);
Order order = new Order();
order.setUserId(userId);
order.setCommodityCode(commodityCode);
order.setCount(orderCount);
order.setMoney(orderMoney);
// INSERT INTO orders ...
return dao.insert(order);
}
protected int calculate(String commodityCode, int orderCount) {
return 100;
}
}

View File

@ -0,0 +1,13 @@
server.port=0
dubbo.application.name=dubbo-fescar-order
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
jdbc.username=root
jdbc.password=root
fescar.applicationId=dubbo-fescar-order
fescar.txServiceGroup=my_test_tx_group

View File

@ -0,0 +1,7 @@
log4j.rootLogger=debug,Console
log4j.logger.org.eclipse.jetty=info
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n

View File

@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar-storage</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-fescar</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-dubbo-alibaba</artifactId>
<version>${fescar.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-nutz-dao</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,30 @@
package io.nutz.demo.dubbo.rpc;
import org.nutz.boot.NbApp;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import io.nutz.demo.bean.Storage;
@IocBean(create="init")
public class DemoFescarStorageServiceLauncher {
@Inject Dao dao;
public void init() {
dao.create(Storage.class, false);
if (dao.count(Storage.class, Cnd.where("commodityCode", "=", "C00321")) == 0) {
Storage storage = new Storage();
storage.setCommodityCode("C00321");
storage.setCount(100);
dao.insert(storage);
}
}
public static void main(String[] args) throws Exception {
new NbApp().run();
}
}

View File

@ -0,0 +1,36 @@
package io.nutz.demo.dubbo.rpc.service.impl;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fescar.core.context.RootContext;
import io.nutz.demo.bean.Storage;
import io.nutz.demo.dubbo.rpc.service.StorageService;
@IocBean
@Service(interfaceClass=StorageService.class)
public class StorageServiceImpl implements StorageService {
private static final Log log = Logs.get();
@Inject
private Dao dao;
@Override
public void deduct(String commodityCode, int count) {
log.info("Storage Service Begin ... xid: " + RootContext.getXID());
log.infof("Deducting inventory SQL: update storage_tbl set count = count - %s where commodity_code = %s", count, commodityCode);
dao.update(Storage.class, Chain.makeSpecial("count", "-" + count), Cnd.where("commodityCode", "=", commodityCode));
log.info("Storage Service End ... ");
}
}

View File

@ -0,0 +1,14 @@
server.port=0
dubbo.application.name=dubbo-fescar-storage
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
jdbc.username=root
jdbc.password=root
fescar.applicationId=dubbo-fescar-storage
fescar.txServiceGroup=my_test_tx_group

View File

@ -0,0 +1,7 @@
log4j.rootLogger=debug,Console
log4j.logger.org.eclipse.jetty=info
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n

View File

@ -0,0 +1,55 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar-web</artifactId>
<dependencies>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-nutz-mvc</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo-dubbo-fescar-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-fescar</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-dubbo-alibaba</artifactId>
<version>${fescar.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-nutz-dao</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,67 @@
package io.nutz.demo.dubbo.rpc;
import org.nutz.boot.NbApp;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import io.nutz.demo.bean.Account;
import io.nutz.demo.bean.Storage;
import io.nutz.demo.dubbo.rpc.service.BusinessService;
@IocBean
public class DemoFescarWebLauncher {
private static final Log log = Logs.get();
@Inject
protected BusinessService businessService;
// 订购信息
@Ok("json:full")
@At("/api/purchase")
public NutMap purchase(String userId, String commodityCode, int orderCount, boolean dofail) {
try {
businessService.purchase(userId, commodityCode, orderCount, dofail);
return new NutMap("ok", true);
}
catch (Throwable e) {
log.debug("purchase fail", e);
return new NutMap("ok", false);
}
}
// --------------------------------------------
@Inject
protected Dao dao;
// 用于页面显示数据
@Ok("json:full")
@At("/api/info")
public NutMap info() {
NutMap re = new NutMap();
NutMap data = new NutMap();
data.put("account", dao.fetch(Account.class, Cnd.where("userId", "=", "U100001")));
data.put("storage", dao.fetch(Storage.class, Cnd.where("commodityCode", "=", "C00321")));
return re.setv("data", data).setv("ok", true);
}
// 要启动zk做dubbo注册服务, fescar-server也需要下载启动
// 数据库名称 fescar_demo, 用户名密码均为root,可以在application.properties里面修改
//启动顺序: account,storage,order,web, 服务启动完成后再启动下一个
// 页面操作: http://127.0.0.1:8080/
//正常操作:
// http://127.0.0.1:8080/api/purchase?userId=U100001&commodityCode=C00321&orderCount=1
// 故意抛出异常:
// http://127.0.0.1:8080/api/purchase?userId=U100001&commodityCode=C00321&orderCount=1&dofail=true
public static void main(String[] args) throws Exception {
new NbApp().run();
}
}

View File

@ -0,0 +1,44 @@
package io.nutz.demo.dubbo.rpc.service.impl;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fescar.core.context.RootContext;
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
import io.nutz.demo.dubbo.rpc.service.BusinessService;
import io.nutz.demo.dubbo.rpc.service.OrderService;
import io.nutz.demo.dubbo.rpc.service.StorageService;
@IocBean
public class BusinessServiceImpl implements BusinessService {
private static final Log log = Logs.get();
@Inject
@Reference
private StorageService storageService;
@Inject
@Reference
private OrderService orderService;
/**
* purchase
*/
@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")
public void purchase(String userId, String commodityCode, int orderCount, boolean dofail) {
log.info("purchase begin ... xid: " + RootContext.getXID());
storageService.deduct(commodityCode, orderCount);
orderService.create(userId, commodityCode, orderCount);
// for test
if (dofail)
throw new RuntimeException("just make it failed");
}
}

View File

@ -0,0 +1,14 @@
server.port=8080
server.host=0.0.0.0
dubbo.application.name=dubbo-fescar-web
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false
jdbc.url=jdbc:mysql://127.0.0.1/fescar_demo
jdbc.username=root
jdbc.password=root
fescar.applicationId=dubbo-fescar-web
fescar.txServiceGroup=my_test_tx_group

View File

@ -0,0 +1,7 @@
log4j.rootLogger=debug,Console
log4j.logger.org.eclipse.jetty=info
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%-5p] %d{HH:mm:ss.SSS} %l - %m%n

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Fescar分布式事务演示</title>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="app">
<div>
<span>当前余额: </span><input v-model="account_money" disabled="disabled">
</div>
<div>
<span>剩余库存: </span><input v-model="storage_count" disabled="disabled">
</div>
<div>
<button @click="buyit(false)">购买并成功</button>
</div>
<div>
<button @click="buyit(true)">购买但失败</button>
</div>
<div>
<button @click="dataReload">刷新</button>
</div>
</div>
</body>
<script type="text/javascript">
var _app = new Vue({
el : "#app",
data : {
account_money : 0,
storage_count : 0
},
methods : {
dataReload : function() {
$.ajax({
url : "api/info",
success : function(re) {
if (re && re.ok) {
_app.account_money = re.data.account.money;
_app.storage_count = re.data.storage.count;
}
}
});
},
buyit : function(dofail) {
$.ajax({
url : "api/purchase?userId=U100001&commodityCode=C00321&orderCount=1&dofail=" + dofail,
success : function(re) {
if (re && re.ok) {
alert("真的是购买成功");
}
else {
alert("真的是购买失败");
}
_app.dataReload();
}
});
}
}
});
_app.dataReload();
</script>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,26 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-demo</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-demo-dubbo-fescar</artifactId>
<packaging>pom</packaging>
<modules>
<module>nutzboot-demo-dubbo-fescar-common</module>
<module>nutzboot-demo-dubbo-fescar-web</module>
<module>nutzboot-demo-dubbo-fescar-order</module>
<module>nutzboot-demo-dubbo-fescar-account</module>
<module>nutzboot-demo-dubbo-fescar-storage</module>
</modules>
<properties>
</properties>
<dependencies>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -34,5 +34,20 @@
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -2,7 +2,6 @@ server.port=8080
server.host=0.0.0.0
dubbo.application.name=dubbo-rpc-client
#dubbo.registry.address=multicast://224.5.6.7:1234
#dubbo.protocol.name=dubbo
#dubbo.protocol.port=20880
#dubbo.annotation.package=io.nutz.demo.dubbo.rpc
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false

View File

@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@ -26,5 +27,19 @@
<artifactId>netty-all</artifactId>
<version>4.1.34.Final</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -1,7 +1,6 @@
server.port=0
dubbo.application.name=dubbo-rpc-service
#dubbo.registry.address=multicast://224.5.6.7:1234
#dubbo.protocol.name=dubbo
#dubbo.protocol.port=20880
#dubbo.annotation.package=io.nutz.demo.dubbo.rpc
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.application.qos.enable=false

View File

@ -13,6 +13,7 @@
<module>nutzboot-demo-dubbo-rpc-service</module>
</modules>
<properties>
<zkclient.version>0.11</zkclient.version>
</properties>
<dependencies>

View File

@ -19,6 +19,7 @@
<module>nutzboot-demo-cloud</module>
<module>nutzboot-demo-servicecomb</module>
<module>nutzboot-demo-custom</module>
<module>nutzboot-demo-dubbo-fescar</module>
</modules>
<properties>
<docker.image.prefix>nutzboot</docker.image.prefix>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter</artifactId>
<version>2.3.3-SNAPSHOT</version>
</parent>
<artifactId>nutzboot-starter-fescar</artifactId>
<name>nutzboot-starter-fescar</name>
<dependencies>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-rm-datasource</artifactId>
<version>${fescar.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fescar</groupId>
<artifactId>fescar-spring</artifactId>
<version>${fescar.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,8 @@
package org.nutz.boot.starter.fescar;
import com.alibaba.fescar.config.ConfigurationFactory;
public class FescarHelper {
public static boolean disableGlobalTransaction = ConfigurationFactory.getInstance().getBoolean("service.disableGlobalTransaction", false);
}

View File

@ -0,0 +1,82 @@
package org.nutz.boot.starter.fescar;
import org.nutz.boot.AppContext;
import org.nutz.boot.annotation.PropDoc;
import org.nutz.boot.starter.ServerFace;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import com.alibaba.fescar.common.util.StringUtils;
import com.alibaba.fescar.rm.RMClient;
import com.alibaba.fescar.tm.TMClient;
@IocBean
public class FescarStarter implements ServerFace {
private static final Log log = Logs.get();
protected static final String PRE = "fescar.";
@PropDoc(value = "fescar应用id", need = true)
public static String PROP_APPID = PRE + "applicationId";
@PropDoc(value = "fescar事务组", need = true)
public static String PROP_TXGROUP = PRE + "txServiceGroup";
@PropDoc(value = "自动创建undo表", defaultValue = "true")
public static String PROP_CREATE_UNDO = PRE + "create_undo_table";
@Inject
protected PropertiesProxy conf;
@Inject
protected AppContext appContext;
private String applicationId;
private String txServiceGroup;
@Override
public void start() throws Exception {
if (FescarHelper.disableGlobalTransaction) {
if (log.isInfoEnabled()) {
log.info("Global transaction is disabled.");
}
return;
}
if (!conf.getBoolean("fescar.enable", true)) {
log.info("Global transaction is disabled.");
return;
}
applicationId = conf.check(PROP_APPID);
txServiceGroup = conf.check(PROP_TXGROUP);
log.infof("fescar applicationId=%s txServiceGroup=%s", applicationId, txServiceGroup);
initClient();
}
protected void initClient() {
if (log.isInfoEnabled()) {
log.info("Initializing Global Transaction Clients ... ");
}
if (StringUtils.isNullOrEmpty(applicationId) || StringUtils.isNullOrEmpty(txServiceGroup)) {
throw new IllegalArgumentException("applicationId: " + applicationId + ", txServiceGroup: " + txServiceGroup);
}
// init TM
TMClient.init(applicationId, txServiceGroup);
if (log.isInfoEnabled()) {
log.info("Transaction Manager Client is initialized. applicationId[" + applicationId + "] txServiceGroup[" + txServiceGroup + "]");
}
// init RM
RMClient.init(applicationId, txServiceGroup);
if (log.isInfoEnabled()) {
log.info("Resource Manager is initialized. applicationId[" + applicationId + "] txServiceGroup[" + txServiceGroup + "]");
}
if (log.isInfoEnabled()) {
log.info("Global Transaction Clients are initialized. ");
}
}
}

View File

@ -0,0 +1,31 @@
package org.nutz.boot.starter.fescar.aop.lock;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.nutz.aop.MethodInterceptor;
import org.nutz.boot.starter.fescar.FescarHelper;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.aop.SimpleAopMaker;
import org.nutz.ioc.loader.annotation.IocBean;
import com.alibaba.fescar.spring.annotation.GlobalLock;
@IocBean(name = "$aop_fescar_GlobalLock")
public class FescarLockAopMaker extends SimpleAopMaker<GlobalLock> {
public List<? extends MethodInterceptor> makeIt(GlobalLock t, Method method, Ioc ioc) {
if (FescarHelper.disableGlobalTransaction)
return null;
return Arrays.asList(new FescarLockInterceptor());
}
public String[] getName() {
return new String[0];
}
public boolean has(String name) {
return false;
}
}

View File

@ -0,0 +1,37 @@
package org.nutz.boot.starter.fescar.aop.lock;
import java.util.concurrent.Callable;
import org.nutz.aop.InterceptorChain;
import org.nutz.aop.MethodInterceptor;
import com.alibaba.fescar.rm.GlobalLockTemplate;
/**
* 全局锁
* @author wendal
*
*/
public class FescarLockInterceptor implements MethodInterceptor {
private GlobalLockTemplate<Object> globalLockTemplate = new GlobalLockTemplate<>();
public void filter(InterceptorChain chain) throws Throwable {
globalLockTemplate.execute(new Callable<Object>() {
@Override
public Object call() throws Exception {
try {
return chain.doChain().getReturn();
}
catch (Throwable e) {
if (e instanceof Exception) {
throw (Exception) e;
} else {
throw new RuntimeException(e);
}
}
}
});
}
}

View File

@ -0,0 +1,39 @@
package org.nutz.boot.starter.fescar.aop.trans;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.nutz.aop.MethodInterceptor;
import org.nutz.boot.starter.fescar.FescarHelper;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.aop.SimpleAopMaker;
import org.nutz.ioc.loader.annotation.IocBean;
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
import com.alibaba.fescar.tm.api.DefaultFailureHandlerImpl;
import com.alibaba.fescar.tm.api.FailureHandler;
@IocBean(name="$aop_fescar_GlobalTransactional")
public class FescarTransAopMaker extends SimpleAopMaker<GlobalTransactional> {
private static FailureHandler DFT = new DefaultFailureHandlerImpl();
public List<? extends MethodInterceptor> makeIt(GlobalTransactional t, Method method, Ioc ioc) {
if (FescarHelper.disableGlobalTransaction)
return null;
FailureHandler failureHandler = DFT;
if (ioc.has("fescarFailureHandler")) {
failureHandler = ioc.get(FailureHandler.class, "fescarFailureHandler");
}
return Arrays.asList(new FescarTransInterceptor(failureHandler, t, method));
}
public String[] getName() {
return new String[0];
}
public boolean has(String name) {
return false;
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nutz.boot.starter.fescar.aop.trans;
import java.lang.reflect.Method;
import org.nutz.aop.InterceptorChain;
import org.nutz.aop.MethodInterceptor;
import org.nutz.lang.Lang;
import com.alibaba.fescar.common.exception.ShouldNeverHappenException;
import com.alibaba.fescar.common.util.StringUtils;
import com.alibaba.fescar.spring.annotation.GlobalTransactional;
import com.alibaba.fescar.tm.api.DefaultFailureHandlerImpl;
import com.alibaba.fescar.tm.api.FailureHandler;
import com.alibaba.fescar.tm.api.TransactionalExecutor;
import com.alibaba.fescar.tm.api.TransactionalTemplate;
/**
* The type Global transactional interceptor. 全局事务拦截器
*/
public class FescarTransInterceptor implements MethodInterceptor {
private static final FailureHandler DEFAULT_FAIL_HANDLER = new DefaultFailureHandlerImpl();
private final TransactionalTemplate transactionalTemplate = new TransactionalTemplate();
private final FailureHandler failureHandler;
private GlobalTransactional globalTrxAnno;
private String name;
/**
* Instantiates a new Global transactional interceptor.
*
* @param failureHandler the failure handler
*/
public FescarTransInterceptor(FailureHandler failureHandler, GlobalTransactional globalTrxAnno, Method method) {
if (null == failureHandler) {
failureHandler = DEFAULT_FAIL_HANDLER;
}
this.failureHandler = failureHandler;
this.globalTrxAnno = globalTrxAnno;
String name = globalTrxAnno.name();
if (!StringUtils.isNullOrEmpty(name)) {
this.name = name;
}
else
this.name = Lang.simpleMethodDesc(method);
}
@Override
public void filter(InterceptorChain chain) throws Throwable {
try {
transactionalTemplate.execute(new TransactionalExecutor() {
@Override
public Object execute() throws Throwable {
return chain.doChain();
}
@Override
public int timeout() {
return globalTrxAnno.timeoutMills();
}
@Override
public String name() {
return name;
}
});
} catch (TransactionalExecutor.ExecutionException e) {
TransactionalExecutor.Code code = e.getCode();
switch (code) {
case RollbackDone:
throw e.getOriginalException();
case BeginFailure:
failureHandler.onBeginFailure(e.getTransaction(), e.getCause());
throw e.getCause();
case CommitFailure:
failureHandler.onCommitFailure(e.getTransaction(), e.getCause());
throw e.getCause();
case RollbackFailure:
failureHandler.onRollbackFailure(e.getTransaction(), e.getCause());
throw e.getCause();
default:
throw new ShouldNeverHappenException("Unknown TransactionalExecutor.Code: " + code);
}
}
}
}

View File

@ -0,0 +1,75 @@
package org.nutz.boot.starter.fescar.datasource;
import java.sql.Connection;
import java.sql.Statement;
import org.nutz.boot.starter.fescar.FescarHelper;
import org.nutz.boot.starter.fescar.FescarStarter;
import org.nutz.ioc.IocEventListener;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fescar.rm.datasource.DataSourceManager;
import com.alibaba.fescar.rm.datasource.DataSourceProxy;
@IocBean
public class FescarDataSourceHandler implements IocEventListener {
private static final Log log = Logs.get();
@Inject
protected PropertiesProxy conf;
public Object afterBorn(Object obj, String beanName) {
return obj;
}
public Object afterCreate(Object obj, String beanName) {
if (obj == null)
return null;
if (obj instanceof DruidDataSource) {
if (FescarHelper.disableGlobalTransaction) {
if (log.isInfoEnabled()) {
log.info("Global transaction is disabled.");
}
return obj;
}
log.info("proxy DruidDataSource : " + obj.hashCode());
DruidDataSource ds = (DruidDataSource)obj;
DataSourceProxy proxy = new DataSourceProxy(ds, "DEFAULT");
DataSourceManager.get().registerResource(proxy);
if (conf.getBoolean(FescarStarter.PROP_CREATE_UNDO, true)) {
try (Connection conn = ds.getConnection()) {
Statement st = conn.createStatement();
st.execute("CREATE TABLE IF NOT EXISTS " + "`undo_log` (\r\n" +
" `id` bigint(20) NOT NULL AUTO_INCREMENT,\r\n" +
" `branch_id` bigint(20) NOT NULL,\r\n" +
" `xid` varchar(100) NOT NULL,\r\n" +
" `rollback_info` longblob NOT NULL,\r\n" +
" `log_status` int(11) NOT NULL,\r\n" +
" `log_created` datetime NOT NULL,\r\n" +
" `log_modified` datetime NOT NULL,\r\n" +
" `ext` varchar(100) DEFAULT NULL,\r\n" +
" PRIMARY KEY (`id`),\r\n" +
" UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)\r\n" +
") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8");
st.close();
}
catch (Throwable e) {
log.warn("fail to create fescar's undo_log table", e);
}
}
return proxy;
}
return obj;
}
public int getOrder() {
return 0;
}
}

View File

@ -0,0 +1 @@
org.nutz.boot.starter.fescar.FescarStarter

View File

@ -0,0 +1,45 @@
# 阿里开源项目 Sentinel: 分布式系统的流量防卫兵 dubbo适配
nutzboot-starter-sentinel-dubbo
## 控制台启动
* https://github.com/alibaba/Sentinel/releases
```
java -Dserver.port=9090 -Dcsp.sentinel.dashboard.server=localhost:9090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.4.1.jar
```
## 客户端配置
```
#是否启用sentinel客户端
sentinel.enabled=true
#控制台地址
sentinel.csp.sentinel.dashboard.server=localhost:9090
#sentinel客户端端口
sentinel.csp.sentinel.api.port=8721
#sentinel客户端通信间隔毫秒数
sentinel.csp.sentinel.heartbeat.interval.ms=3000
#sentinel客户端本地IP地址,不设置则自动获取
sentinel.csp.sentinel.heartbeat.client.ip=
#规则存储的key名
sentinel.rulekey=nutzboot
#规则存储的发布订阅频道名
sentinel.channel=sentinel
#redis配置内容,用于存储规则,sentinel.enabled=true时初始化加载
redis.host=127.0.0.1
redis.port=6379
redis.timeout=2000
redis.max_redir=10
redis.database=0
redis.maxTotal=100
redis.pool.maxTotal=100
redis.pool.maxIdle=50
redis.pool.minIdle=10
#redis.password=test123
#redis集群模式设置 redis.mode=cluster
redis.mode=normal
#redis.nodes=
```

View File

@ -75,6 +75,7 @@
<module>nutzboot-starter-nacos-config-client</module>
<module>nutzboot-starter-ftp</module>
<module>nutzboot-starter-fastdfs</module>
<module>nutzboot-starter-fescar</module>
</modules>
<dependencies>
<dependency>

View File

@ -46,6 +46,7 @@
<javassist.version>3.24.0-GA</javassist.version>
<fastdfs-client-java.version>1.29.4</fastdfs-client-java.version>
<commons-pool2.version>2.6.1</commons-pool2.version>
<fescar.version>0.4.0</fescar.version>
</properties>
<description>NutzBoot, micoservice base on Nutz</description>
@ -929,6 +930,11 @@
<artifactId>nutzboot-starter-servicecomb</artifactId>
<version>${nutzboot.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-fescar</artifactId>
<version>${nutzboot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>