Commit 48b2532a authored by jianhua.zhang's avatar jianhua.zhang

波场浏览器JAVA版

parent 12093c52
package com.wuban.tron.explore; package com.wuban.tron.explore;
import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.fetch.Engine; import com.wuban.tron.explore.fetch.Engine;
import com.wuban.tron.explore.service.LastBlockService; import com.wuban.tron.explore.service.LastBlockService;
import com.wuban.tron.explore.service.TransactionService; import com.wuban.tron.explore.service.TransactionService;
...@@ -74,7 +75,7 @@ public class Bootstrapper { ...@@ -74,7 +75,7 @@ public class Bootstrapper {
} }
private synchronized void startEngine() { private synchronized void startEngine() {
Engine engine = new Engine("tron"); Engine engine = new Engine(Constant.EXCUTOR_NAME_BLOCK);
engine.start(); engine.start();
} }
......
...@@ -3,6 +3,12 @@ package com.wuban.tron.explore; ...@@ -3,6 +3,12 @@ package com.wuban.tron.explore;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* <core>项目启动类</core>
*
* @author sky
* @date 2020/11/02
*/
@SpringBootApplication @SpringBootApplication
public class ExploreApplication { public class ExploreApplication {
......
...@@ -35,6 +35,8 @@ public class Constant { ...@@ -35,6 +35,8 @@ public class Constant {
public static final String BLOCK_NUM_LIST_KEY = "block_num_list"; public static final String BLOCK_NUM_LIST_KEY = "block_num_list";
public static final String ADDRESS_KEY = "address";
/** /**
* 数据同步阀值 * 数据同步阀值
*/ */
...@@ -50,8 +52,8 @@ public class Constant { ...@@ -50,8 +52,8 @@ public class Constant {
*/ */
public static final int TX_ID_LEN = 64; public static final int TX_ID_LEN = 64;
public static final String EXCUTOR_NAME_ACCOUNT = "tron.account"; public static final String EXCUTOR_NAME_ACCOUNT = "抓取余额Pool";
public static final String EXCUTOR_NAME_BLOCK = "tron.block"; public static final String EXCUTOR_NAME_BLOCK = "抓取区块Pool";
} }
package com.wuban.tron.explore.constant; package com.wuban.tron.explore.constant;
/**
* <core>首页详情枚举类</core>
*
* @author sky
* @date 2020/11/02
*/
public enum HomeSearchTypeEnum { public enum HomeSearchTypeEnum {
ADDRESS_INFO(0,"地址详情"), ADDRESS_INFO(0,"地址详情"),
TRANSACTION_INFO(1, "交易详情"), TRANSACTION_INFO(1, "交易详情"),
BLOCK_INFO(2,"区块详情"); BLOCK_INFO(2,"区块详情");
/**
* code
*/
private int code; private int code;
/**
* 描述
*/
private String desc; private String desc;
HomeSearchTypeEnum(int code, String desc) { HomeSearchTypeEnum(int code, String desc) {
......
package com.wuban.tron.explore.constant; package com.wuban.tron.explore.constant;
/**
* <core>分页常量类</core>
*
* @author sky
* @date 2020/11/02
*/
public class PageConstant { public class PageConstant {
/** /**
......
...@@ -12,6 +12,12 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -12,6 +12,12 @@ import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid; import javax.validation.Valid;
/**
* <core>区块统计API</core>
*
* @author sky
* @date 2020/11/12
*/
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/census") @RequestMapping("/census")
......
...@@ -35,6 +35,12 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -35,6 +35,12 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* <core>API接口</core>
*
* @author sky
* @date 2020/11/02
*/
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/api/tron") @RequestMapping("/api/tron")
......
...@@ -7,6 +7,12 @@ import org.springframework.stereotype.Repository; ...@@ -7,6 +7,12 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/**
* <core>账户DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface AddressRepository { public interface AddressRepository {
......
...@@ -7,9 +7,20 @@ import org.springframework.stereotype.Repository; ...@@ -7,9 +7,20 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/**
* <core>区块统计DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface BlockDayCensusRepository { public interface BlockDayCensusRepository {
/**
* 添加记录
* @param record
* @return
*/
int insert(@Param("record") BlockDayCensus record); int insert(@Param("record") BlockDayCensus record);
/** /**
......
...@@ -7,9 +7,21 @@ import org.springframework.stereotype.Repository; ...@@ -7,9 +7,21 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/**
* <core>区块头DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface BlockHeaderRepository { public interface BlockHeaderRepository {
/**
* 添加记录
*
* @param record
* @return
*/
int insert(@Param("record") BlockHeader record); int insert(@Param("record") BlockHeader record);
/** /**
......
...@@ -5,15 +5,45 @@ import com.wuban.tron.explore.entity.example.LastBlockExample; ...@@ -5,15 +5,45 @@ import com.wuban.tron.explore.entity.example.LastBlockExample;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/**
* <core>最新统计区块DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface LastBlockRepository { public interface LastBlockRepository {
/**
* 获取最新统计的区块
*
* @param id
* @return
*/
LastBlock selectByIdForUpdate(@Param("id") Long id); LastBlock selectByIdForUpdate(@Param("id") Long id);
/**
* 获取最新统计的区块
*
* @param example
* @return
*/
LastBlock selectOneByExample(@Param("example") LastBlockExample example); LastBlock selectOneByExample(@Param("example") LastBlockExample example);
/**
* 更新统计的区块
*
* @param record
* @return
*/
int updateById(@Param("record") LastBlock record); int updateById(@Param("record") LastBlock record);
/**
* 更新统计的区块
*
* @param record
* @return
*/
int updateCurBlockNumById(@Param("record") LastBlock record); int updateCurBlockNumById(@Param("record") LastBlock record);
} }
\ No newline at end of file
...@@ -6,11 +6,28 @@ import org.springframework.stereotype.Repository; ...@@ -6,11 +6,28 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/**
* <core>区块hex DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface TransactionHexRepository { public interface TransactionHexRepository {
/**
* 添加记录
* @param record
* @return
*/
int insert(@Param("record") TransactionHex record); int insert(@Param("record") TransactionHex record);
/**
* 批量添加
*
* @param records
* @return
*/
int batchInsert(@Param("records") List<TransactionHex> records); int batchInsert(@Param("records") List<TransactionHex> records);
} }
...@@ -7,11 +7,29 @@ import org.springframework.stereotype.Repository; ...@@ -7,11 +7,29 @@ import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
/**
* <core>交易DAO</core>
*
* @author sky
* @date 2020/11/02
*/
@Repository @Repository
public interface TransactionRepository { public interface TransactionRepository {
/**
* 添加记录
*
* @param record
* @return
*/
int insert(@Param("record") Transaction record); int insert(@Param("record") Transaction record);
/**
* 批量添加记录
*
* @param records
* @return
*/
int batchInsert(@Param("records") List<Transaction> records); int batchInsert(@Param("records") List<Transaction> records);
/** /**
......
...@@ -4,6 +4,12 @@ import lombok.Data; ...@@ -4,6 +4,12 @@ import lombok.Data;
import java.util.List; import java.util.List;
/**
* <core>波场账户权限信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class ActivePermission { public class ActivePermission {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain;
import lombok.Data; import lombok.Data;
/**
* <core>波场区块交易信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class Contract { public class Contract {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain;
import lombok.Data; import lombok.Data;
/**
* <core>波场区块交易信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class ContractParameter { public class ContractParameter {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain;
import lombok.Data; import lombok.Data;
/**
* <core>波场区块交易信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class ContractParameterValue { public class ContractParameterValue {
......
...@@ -4,6 +4,12 @@ import lombok.Data; ...@@ -4,6 +4,12 @@ import lombok.Data;
import java.util.List; import java.util.List;
/**
* <core>波场账户权限信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class OwnerPermission { public class OwnerPermission {
......
...@@ -4,6 +4,12 @@ import lombok.Data; ...@@ -4,6 +4,12 @@ import lombok.Data;
import java.util.List; import java.util.List;
/**
* <core>波场区块交易信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class TransactionsRawData { public class TransactionsRawData {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain;
import lombok.Data; import lombok.Data;
/**
* <core>波场区块账号信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class TronAccount { public class TronAccount {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.domain;
import lombok.Data; import lombok.Data;
/**
* <core>波场区块头信息</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class TronBlockHeader { public class TronBlockHeader {
......
...@@ -9,16 +9,16 @@ import lombok.extern.slf4j.Slf4j; ...@@ -9,16 +9,16 @@ import lombok.extern.slf4j.Slf4j;
* @date 2020/11/04 * @date 2020/11/04
*/ */
@Slf4j @Slf4j
public abstract class Job implements Runnable { public abstract class AbstractJob implements Runnable {
/** /**
* 是否循环执行 * 是否循环执行
*/ */
private volatile boolean loop; private volatile boolean loop;
public Job() {this.loop = true;} public AbstractJob() {this.loop = true;}
public Job(final boolean loop) { public AbstractJob(final boolean loop) {
this.loop = loop; this.loop = loop;
} }
...@@ -37,6 +37,11 @@ public abstract class Job implements Runnable { ...@@ -37,6 +37,11 @@ public abstract class Job implements Runnable {
return !this.loop; return !this.loop;
} }
/**
* 执行方法
*
* @return
*/
public abstract boolean execute(); public abstract boolean execute();
} }
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.fetch;
import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.domain.TronAccount; import com.wuban.tron.explore.domain.TronAccount;
import com.wuban.tron.explore.entity.Address; import com.wuban.tron.explore.entity.Address;
import com.wuban.tron.explore.service.AddressService; import com.wuban.tron.explore.service.AddressService;
...@@ -23,13 +22,14 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -23,13 +22,14 @@ import java.util.concurrent.atomic.AtomicInteger;
* @date 2020/11/04 * @date 2020/11/04
*/ */
@Slf4j @Slf4j
public class AccountBalanceTask extends Job { @Deprecated
public class AccountBalanceTask extends AbstractJob {
private AddressService addressService = SpringContextUtil.getBean(AddressService.class); private AddressService addressService = SpringContextUtil.getBean(AddressService.class);
private static final int SIZE = 50; private static final int SIZE = 2;
private String name = "AccountBalanceThreadPool"; private String name = "账户余额持久化线程池";
private static ThreadPoolExecutor threadPool; private static ThreadPoolExecutor threadPool;
...@@ -38,11 +38,11 @@ public class AccountBalanceTask extends Job { ...@@ -38,11 +38,11 @@ public class AccountBalanceTask extends Job {
private Set<String> dataSet; private Set<String> dataSet;
public AccountBalanceTask() { public AccountBalanceTask() {
initPool();
} }
public AccountBalanceTask(Set<String> dataSet) { public AccountBalanceTask(Set<String> dataSet) {
this.dataSet = dataSet; this.dataSet = dataSet;
initPool();
} }
public void fetch(String address) { public void fetch(String address) {
...@@ -69,9 +69,9 @@ public class AccountBalanceTask extends Job { ...@@ -69,9 +69,9 @@ public class AccountBalanceTask extends Job {
public synchronized void initPool() { public synchronized void initPool() {
if (threadPool == null) { if (threadPool == null) {
threadPool = new ThreadPoolExecutor(SIZE, SIZE * 2, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), threadPool = new ThreadPoolExecutor(SIZE, SIZE*2, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new ExecutorThreadFactory()); new ExecutorThreadFactory());
log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", name, SIZE, SIZE * 2); log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", name, SIZE, SIZE*2);
} }
} }
......
package com.wuban.tron.explore.fetch;
import com.wuban.tron.explore.handler.AddressBalanceHandler;
import com.wuban.tron.explore.handler.IAddressBalanceHandler;
import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.domain.TronAccount;
import com.wuban.tron.explore.service.TronService;
import com.wuban.tron.explore.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <core>区块数据抓取者服务接口方法实现类</core>
*
* @author sky
* @date 2020/11/12
*/
@Slf4j
public class AddressBalanceFetcher<T> extends AbstractJob implements IAddressBalanceFetcher {
private TronService tronService;
private IAddressBalanceHandler handler;
private StringRedisTemplate stringRedisTemplate;
AddressBalanceFetcher(final AddressBalanceHandler handler) {
this.handler = handler;
tronService = SpringContextUtil.getBean(TronService.class);
stringRedisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
}
@Override
public List fetch() {
List<TronAccount> dataList = new ArrayList<>();
Long num = 0L;
try {
// Redis 获取账户地址
String address = this.stringRedisTemplate.opsForSet().pop(Constant.ADDRESS_KEY);
if (!StringUtils.isEmpty(address)) {
TronAccount data = tronService.getAccount(address);
if (data != null && data.getBalance() != null) {
dataList.add(data);
}
}
} catch (Exception e) {
log.info(e.getMessage(), e);
}
return dataList;
}
@Override
public void send(List list) throws InterruptedException {
if (CollectionUtils.isEmpty(list)) {
return;
}
this.handler.receive(list);
}
@Override
public boolean execute() {
try {
final List<TronAccount> list = fetch();
if (CollectionUtils.isEmpty(list)) {
return false;
}
send(list);
return true;
} catch (final Exception e) {
log.error("fetch exception", e);
return false;
}
}
}
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.fetch;
import com.wuban.tron.explore.handler.BlockDataHandler;
import com.wuban.tron.explore.handler.IBlockDataHandler;
import com.wuban.tron.explore.constant.Constant; import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.domain.TronResponseData; import com.wuban.tron.explore.domain.TronResponseData;
import com.wuban.tron.explore.service.LastBlockService; import com.wuban.tron.explore.service.LastBlockService;
...@@ -20,7 +22,7 @@ import java.util.List; ...@@ -20,7 +22,7 @@ import java.util.List;
* @date 2020/11/04 * @date 2020/11/04
*/ */
@Slf4j @Slf4j
public class BlockDataFetcher<T> extends Job implements IBlockDataFetcher { public class BlockDataFetcher<T> extends AbstractJob implements IBlockDataFetcher {
private TronService tronService; private TronService tronService;
...@@ -32,7 +34,6 @@ public class BlockDataFetcher<T> extends Job implements IBlockDataFetcher { ...@@ -32,7 +34,6 @@ public class BlockDataFetcher<T> extends Job implements IBlockDataFetcher {
BlockDataFetcher(final BlockDataHandler handler) { BlockDataFetcher(final BlockDataHandler handler) {
this.handler = handler; this.handler = handler;
//lastBlockService = SpringContextUtil.getBean(LastBlockService.class);
tronService = SpringContextUtil.getBean(TronService.class); tronService = SpringContextUtil.getBean(TronService.class);
stringRedisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class); stringRedisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
} }
...@@ -58,7 +59,6 @@ public class BlockDataFetcher<T> extends Job implements IBlockDataFetcher { ...@@ -58,7 +59,6 @@ public class BlockDataFetcher<T> extends Job implements IBlockDataFetcher {
} }
} catch (Exception e) { } catch (Exception e) {
log.info(e.getMessage(), e); log.info(e.getMessage(), e);
log.error("区块高度 num:{}同步DB失败",num);
} }
return dataList; return dataList;
......
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.fetch;
import com.wuban.tron.explore.handler.AddressBalanceHandler;
import com.wuban.tron.explore.handler.BlockDataHandler;
import com.wuban.tron.explore.domain.TronAccount;
import com.wuban.tron.explore.domain.TronResponseData; import com.wuban.tron.explore.domain.TronResponseData;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -32,6 +35,18 @@ public class Engine { ...@@ -32,6 +35,18 @@ public class Engine {
*/ */
private BlockDataHandler handler; private BlockDataHandler handler;
/**
* 账户余额猎手
*/
private AddressBalanceFetcher<TronAccount> addressFetcher;
/**
* 账户余额处理者
*/
private AddressBalanceHandler addressHandler;
public static final int FETCHER_NUM = 5;
public Engine(String name) { public Engine(String name) {
this.executor = new Executor(name); this.executor = new Executor(name);
this.monitor = new Thread(() -> { this.monitor = new Thread(() -> {
...@@ -54,14 +69,25 @@ public class Engine { ...@@ -54,14 +69,25 @@ public class Engine {
} }
public synchronized void start() { public synchronized void start() {
/*
区块数据抓取、处理
*/
this.handler = new BlockDataHandler(); this.handler = new BlockDataHandler();
this.fetcher = new BlockDataFetcher(this.handler); this.fetcher = new BlockDataFetcher(this.handler);
this.executor.execute(this.handler); this.executor.execute(this.handler);
//int cupNum = ThreadPoolUtil.getCupNum()*2; //int cupNum = ThreadPoolUtil.getCupNum()*2;
for (int i = 0; i <= 10; i++) { for (int i = 0; i <= FETCHER_NUM; i++) {
this.executor.execute(this.fetcher); this.executor.execute(this.fetcher);
} }
/*
账户余额抓取、处理
*/
this.addressHandler = new AddressBalanceHandler();
this.addressFetcher = new AddressBalanceFetcher(this.addressHandler);
this.executor.execute(this.addressHandler);
this.executor.execute(this.addressFetcher);
} }
public synchronized void reload() { public synchronized void reload() {
......
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.fetch;
import com.wuban.tron.explore.constant.Constant;
import com.wuban.tron.explore.util.ThreadPoolUtil; import com.wuban.tron.explore.util.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -12,29 +11,28 @@ import java.util.concurrent.ThreadPoolExecutor; ...@@ -12,29 +11,28 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/**
* <core>线程池</core>
*
* @author sky
* @date 2020/11/02
*/
@Slf4j @Slf4j
public class Executor { public class Executor {
private static final int SIZE = 20; private static final int SIZE = 10;
private final List<Job> jobList = new ArrayList<>(); private final List<AbstractJob> jobList = new ArrayList<>();
private final String name; private final String name;
private ThreadPoolExecutor pool; private ThreadPoolExecutor pool;
public Executor(final String name) { public Executor(final String name) {
this.name = name; this.name = name;
this.pool = new ThreadPoolExecutor(SIZE, SIZE * 2, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), this.pool = new ThreadPoolExecutor(SIZE, SIZE * 3, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new ExecutorThreadFactory()); new ExecutorThreadFactory());
log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", name, SIZE, SIZE * 2); log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", name, SIZE, SIZE * 3);
} }
public Executor(final String name, final int size) { public void execute(final AbstractJob r) {
this.name = name;
this.pool = new ThreadPoolExecutor(size, size * 2, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
new ExecutorThreadFactory());
log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", name, size, size * 2);
}
public void execute(final Job r) {
this.pool.execute(r); this.pool.execute(r);
this.jobList.add(r); this.jobList.add(r);
} }
...@@ -59,8 +57,7 @@ public class Executor { ...@@ -59,8 +57,7 @@ public class Executor {
ExecutorThreadFactory() { ExecutorThreadFactory() {
final SecurityManager s = System.getSecurityManager(); final SecurityManager s = System.getSecurityManager();
this.group = (s != null) ? s.getThreadGroup() : this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
Thread.currentThread().getThreadGroup();
this.namePrefix = "excutor-" + Executor.this.name + "-thread-"; this.namePrefix = "excutor-" + Executor.this.name + "-thread-";
} }
......
package com.wuban.tron.explore.fetch;
import java.util.List;
/**
* <core>用户余额数据抓取者服务接口方法</core>
*
* @author sky
* @date 2020/11/12
*/
public interface IAddressBalanceFetcher<T> {
/**
* 抓取数据
*
* @return
*/
List<T> fetch();
/**
* 发送数据
*
* @param list
* @throws InterruptedException
*/
void send(final List<T> list) throws InterruptedException;
}
...@@ -10,8 +10,19 @@ import java.util.List; ...@@ -10,8 +10,19 @@ import java.util.List;
*/ */
public interface IBlockDataFetcher<T> { public interface IBlockDataFetcher<T> {
/**
* 抓取数据
*
* @return
*/
List<T> fetch(); List<T> fetch();
/**
* 发送数据
*
* @param orders
* @throws InterruptedException
*/
void send(final List<T> orders) throws InterruptedException; void send(final List<T> orders) throws InterruptedException;
} }
...@@ -26,9 +26,8 @@ public class PersistThreadPool { ...@@ -26,9 +26,8 @@ public class PersistThreadPool {
public PersistThreadPool() { public PersistThreadPool() {
for (int i = 0; i < POLL_SIZE; i++) { for (int i = 0; i < POLL_SIZE; i++) {
executors.add(new ThreadPoolExecutor(POLL_SIZE, POLL_SIZE * 5, 30L, TimeUnit.SECONDS, executors.add(new ThreadPoolExecutor(POLL_SIZE, POLL_SIZE * 5, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(), new LinkedBlockingQueue<>(), new PersistThreadFactory(i)));
new PersistThreadFactory(i)));
} }
log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", "PersistThreadPool", POLL_SIZE, POLL_SIZE * 5); log.info("初始化线程池 name:{} coreSize:{} maxSize:{}", "PersistThreadPool", POLL_SIZE, POLL_SIZE * 5);
} }
...@@ -49,25 +48,20 @@ public class PersistThreadPool { ...@@ -49,25 +48,20 @@ public class PersistThreadPool {
* The persist thread factory * The persist thread factory
*/ */
static class PersistThreadFactory implements ThreadFactory { static class PersistThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1); private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
private final ThreadGroup group; private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1); private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix; private final String namePrefix;
PersistThreadFactory(final int index) { PersistThreadFactory(final int index) {
final SecurityManager s = System.getSecurityManager(); final SecurityManager s = System.getSecurityManager();
this.group = (s != null) ? s.getThreadGroup() : this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
Thread.currentThread().getThreadGroup(); this.namePrefix = "persist-pool" + index + "-" + POOL_NUMBER.getAndIncrement() + "-thread-";
this.namePrefix = "persist-pool" + index +
"-" + poolNumber.getAndIncrement() +
"-thread-";
} }
@Override @Override
public Thread newThread(final Runnable r) { public Thread newThread(final Runnable r) {
final Thread t = new Thread(this.group, r, final Thread t = new Thread(this.group, r,this.namePrefix + this.threadNumber.getAndIncrement(),0);
this.namePrefix + this.threadNumber.getAndIncrement(),
0);
if (t.isDaemon()) { t.setDaemon(false); } if (t.isDaemon()) { t.setDaemon(false); }
if (t.getPriority() != Thread.NORM_PRIORITY) { t.setPriority(Thread.NORM_PRIORITY); } if (t.getPriority() != Thread.NORM_PRIORITY) { t.setPriority(Thread.NORM_PRIORITY); }
return t; return t;
......
package com.wuban.tron.explore.handler;
import com.wuban.tron.explore.domain.TronAccount;
import com.wuban.tron.explore.entity.Address;
import com.wuban.tron.explore.fetch.AbstractJob;
import com.wuban.tron.explore.fetch.PersistThreadPool;
import com.wuban.tron.explore.service.AddressService;
import com.wuban.tron.explore.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/**
* <core>账户余额处理者服务接口方法实现类</core>
*
* @author sky
* @date 2020/11/12
*/
@Slf4j
public class AddressBalanceHandler extends AbstractJob implements IAddressBalanceHandler<TronAccount> {
private AddressService addressService;
private PersistThreadPool threadPool;
private final LinkedBlockingQueue<List<TronAccount>> dataList;
public AddressBalanceHandler() {
this.dataList = new LinkedBlockingQueue<>();
addressService = SpringContextUtil.getBean(AddressService.class);
threadPool = new PersistThreadPool();
}
@Override
public boolean execute() {
final List<TronAccount> list = this.dataList.poll();
if(list != null && list.size() != 0) {
threadPool.getPool().execute(() -> flush(list));
}
return true;
}
@Override
public void receive(List<TronAccount> e) throws InterruptedException {
if (!CollectionUtils.isEmpty(e)) {
this.dataList.put(e);
}
}
@Override
public void flush(List<TronAccount> e) {
if (!CollectionUtils.isEmpty(e)) {
Address obj = new Address();
obj.setAddress(e.get(0).getAddress());
obj.setBalance(e.get(0).getBalance());
this.addressService.updateById(obj);
log.info("更新账户余额 account:{}", obj.toString());
}
}
}
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.handler;
import com.wuban.tron.explore.domain.TronResponseData; import com.wuban.tron.explore.domain.TronResponseData;
import com.wuban.tron.explore.fetch.AbstractJob;
import com.wuban.tron.explore.fetch.PersistThreadPool;
import com.wuban.tron.explore.service.TransactionService; import com.wuban.tron.explore.service.TransactionService;
import com.wuban.tron.explore.util.SpringContextUtil; import com.wuban.tron.explore.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -16,7 +18,7 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -16,7 +18,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* @date 2020/11/04 * @date 2020/11/04
*/ */
@Slf4j @Slf4j
public class BlockDataHandler extends Job implements IBlockDataHandler { public class BlockDataHandler extends AbstractJob implements IBlockDataHandler {
private TransactionService transactionService; private TransactionService transactionService;
...@@ -24,12 +26,9 @@ public class BlockDataHandler extends Job implements IBlockDataHandler { ...@@ -24,12 +26,9 @@ public class BlockDataHandler extends Job implements IBlockDataHandler {
private final LinkedBlockingQueue<List<TronResponseData>> dataList; private final LinkedBlockingQueue<List<TronResponseData>> dataList;
BlockDataHandler() { public BlockDataHandler() {
this.dataList = new LinkedBlockingQueue<>(); this.dataList = new LinkedBlockingQueue<>();
transactionService = SpringContextUtil.getBean(TransactionService.class); transactionService = SpringContextUtil.getBean(TransactionService.class);
if (transactionService != null) {
this.transactionService.init();
}
threadPool = new PersistThreadPool(); threadPool = new PersistThreadPool();
} }
......
package com.wuban.tron.explore.handler;
import java.util.List;
/**
* <core>账户余额处理者服务接口方法</core>
*
* @author sky
* @date 2020/11/12
*/
public interface IAddressBalanceHandler<T> {
/**
* 接收用户余额数据
*
* @param e 区块数据
* @throws InterruptedException 异常
*/
void receive(List<T> e) throws InterruptedException;
/**
* 数据刷入DB
*
* @param e 用户余额数据
*/
void flush(List<T> e);
}
package com.wuban.tron.explore.fetch; package com.wuban.tron.explore.handler;
import java.util.List; import java.util.List;
......
...@@ -4,6 +4,12 @@ import lombok.Data; ...@@ -4,6 +4,12 @@ import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
/**
* <core>统计请求参数</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class CensusRequest { public class CensusRequest {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.request; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.request;
import lombok.Data; import lombok.Data;
/**
* <core>分页请求参数</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class PageRequest { public class PageRequest {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.request; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.request;
import lombok.Data; import lombok.Data;
/**
* <core>搜索请求参数</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class SearchRequest extends PageRequest { public class SearchRequest extends PageRequest {
......
...@@ -7,7 +7,7 @@ import java.util.List; ...@@ -7,7 +7,7 @@ import java.util.List;
/** /**
* 分页结果类 * 分页结果类
* @author wuban-team * @author wuban-team
* @date 2020-10-15 * @date 2020-11-05
*/ */
@Data @Data
public class SelfPageInfo<T> { public class SelfPageInfo<T> {
......
...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.response; ...@@ -2,6 +2,12 @@ package com.wuban.tron.explore.param.response;
import lombok.Data; import lombok.Data;
/**
* <core>交易MODEL</core>
*
* @author sky
* @date 2020/11/02
*/
@Data @Data
public class TransactionModel { public class TransactionModel {
......
...@@ -7,6 +7,12 @@ import org.apache.ibatis.annotations.Param; ...@@ -7,6 +7,12 @@ import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
/**
* <core>账户服务接口</core>
*
* @author sky
* @date 2020/11/02
*/
public interface AddressService { public interface AddressService {
/** /**
...@@ -35,6 +41,8 @@ public interface AddressService { ...@@ -35,6 +41,8 @@ public interface AddressService {
* 分页查询 * 分页查询
* *
* @param example 查询条件参数 * @param example 查询条件参数
* @param startIndex
* @param pageSize
* @return 分页记录列表 * @return 分页记录列表
*/ */
PageInfo<Address> selectByPager(Integer startIndex, Integer pageSize, AddressExample example); PageInfo<Address> selectByPager(Integer startIndex, Integer pageSize, AddressExample example);
......
...@@ -6,6 +6,12 @@ import com.wuban.tron.explore.entity.example.BlockDayCensusExample; ...@@ -6,6 +6,12 @@ import com.wuban.tron.explore.entity.example.BlockDayCensusExample;
import java.util.List; import java.util.List;
/**
* <core>区块统计服务接口</core>
*
* @author sky
* @date 2020/11/02
*/
public interface BlockDayCensusService { public interface BlockDayCensusService {
/** /**
...@@ -18,7 +24,12 @@ public interface BlockDayCensusService { ...@@ -18,7 +24,12 @@ public interface BlockDayCensusService {
*/ */
PageInfo<BlockDayCensus> getByPageWithCategory(Integer startIndex, Integer pageSize, BlockDayCensusExample example); PageInfo<BlockDayCensus> getByPageWithCategory(Integer startIndex, Integer pageSize, BlockDayCensusExample example);
/**
* 获取统计列表
*
* @param example 检索条件
* @return
*/
List<BlockDayCensus> getByExample(BlockDayCensusExample example); List<BlockDayCensus> getByExample(BlockDayCensusExample example);
......
...@@ -4,6 +4,12 @@ import com.wuban.tron.explore.entity.BlockHeader; ...@@ -4,6 +4,12 @@ import com.wuban.tron.explore.entity.BlockHeader;
import com.wuban.tron.explore.entity.example.BlockHeaderExample; import com.wuban.tron.explore.entity.example.BlockHeaderExample;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
/**
* <core>区块头服务接口</core>
*
* @author sky
* @date 2020/11/02
*/
public interface BlockHeaderService { public interface BlockHeaderService {
/** /**
......
...@@ -23,6 +23,11 @@ public interface TransactionService { ...@@ -23,6 +23,11 @@ public interface TransactionService {
*/ */
void save(List<TronResponseData> dataList); void save(List<TronResponseData> dataList);
/**
* 获取所有区块中时间最小的
*
* @return
*/
Long getBlockMinTime(); Long getBlockMinTime();
/** /**
...@@ -74,6 +79,5 @@ public interface TransactionService { ...@@ -74,6 +79,5 @@ public interface TransactionService {
*/ */
PageInfo<Transaction> selectListByAddress(String address, int type, Integer startIndex, Integer pageSize); PageInfo<Transaction> selectListByAddress(String address, int type, Integer startIndex, Integer pageSize);
void init();
} }
...@@ -16,6 +16,7 @@ public interface TronService { ...@@ -16,6 +16,7 @@ public interface TronService {
* 按照高度查询block * 按照高度查询block
* *
* @param blockNum 是块的高度 * @param blockNum 是块的高度
* @return
*/ */
TronResponseData getBlockByNum(Long blockNum); TronResponseData getBlockByNum(Long blockNum);
...@@ -23,6 +24,7 @@ public interface TronService { ...@@ -23,6 +24,7 @@ public interface TronService {
* 查询最新的几个块 * 查询最新的几个块
* *
* @param num 块的数量 * @param num 块的数量
* @return
*/ */
TronResponseArrayData getBlockByLatestNum(Integer num); TronResponseArrayData getBlockByLatestNum(Integer num);
......
...@@ -12,6 +12,12 @@ import org.springframework.stereotype.Service; ...@@ -12,6 +12,12 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
/**
* <core>账户服务接口实现类</core>
*
* @author sky
* @date 2020/11/02
*/
@Service @Service
@RequiredArgsConstructor(onConstructor_ = @Autowired) @RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AddressServiceImpl implements AddressService { public class AddressServiceImpl implements AddressService {
......
...@@ -13,6 +13,12 @@ import org.springframework.stereotype.Service; ...@@ -13,6 +13,12 @@ import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
/**
* <core>区块统计服务接口实现类</core>
*
* @author sky
* @date 2020/11/02
*/
@Service @Service
@RequiredArgsConstructor(onConstructor_ = @Autowired) @RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BlockDayCensusServiceImpl implements BlockDayCensusService { public class BlockDayCensusServiceImpl implements BlockDayCensusService {
......
...@@ -8,6 +8,12 @@ import lombok.RequiredArgsConstructor; ...@@ -8,6 +8,12 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/**
* <core>区块头服务接口实现类</core>
*
* @author sky
* @date 2020/11/02
*/
@Service @Service
@RequiredArgsConstructor(onConstructor_ = @Autowired) @RequiredArgsConstructor(onConstructor_ = @Autowired)
public class BlockHeaderServiceImpl implements BlockHeaderService { public class BlockHeaderServiceImpl implements BlockHeaderService {
......
...@@ -137,7 +137,7 @@ public class LastBlockServiceImpl implements LastBlockService { ...@@ -137,7 +137,7 @@ public class LastBlockServiceImpl implements LastBlockService {
for (long i = startNum; i <= endNum; i++) { for (long i = startNum; i <= endNum; i++) {
conn.lPush(Constant.BLOCK_NUM_LIST_KEY, Long.toString(i)); conn.lPush(Constant.BLOCK_NUM_LIST_KEY, Long.toString(i));
} }
log.info("sync redis block num start={},end={}", startNum, endNum); //log.info("sync redis block num start={},end={}", startNum, endNum);
return null; return null;
} }
}); });
......
...@@ -8,7 +8,6 @@ import com.wuban.tron.explore.dao.*; ...@@ -8,7 +8,6 @@ import com.wuban.tron.explore.dao.*;
import com.wuban.tron.explore.domain.*; import com.wuban.tron.explore.domain.*;
import com.wuban.tron.explore.entity.*; import com.wuban.tron.explore.entity.*;
import com.wuban.tron.explore.entity.example.TransactionExample; import com.wuban.tron.explore.entity.example.TransactionExample;
import com.wuban.tron.explore.fetch.AccountBalanceTask;
import com.wuban.tron.explore.fetch.Executor; import com.wuban.tron.explore.fetch.Executor;
import com.wuban.tron.explore.service.TransactionService; import com.wuban.tron.explore.service.TransactionService;
import com.wuban.tron.explore.util.BigDecimalUtil; import com.wuban.tron.explore.util.BigDecimalUtil;
...@@ -16,6 +15,11 @@ import com.wuban.tron.explore.util.DateUtil; ...@@ -16,6 +15,11 @@ import com.wuban.tron.explore.util.DateUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
...@@ -25,6 +29,12 @@ import java.math.BigDecimal; ...@@ -25,6 +29,12 @@ import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*; import java.util.*;
/**
* <core>区块服务接口方法实现类</core>
*
* @author sky
* @date 2020/11/02
*/
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor(onConstructor_ = @Autowired) @RequiredArgsConstructor(onConstructor_ = @Autowired)
...@@ -42,6 +52,8 @@ public class TransactionServiceImpl implements TransactionService { ...@@ -42,6 +52,8 @@ public class TransactionServiceImpl implements TransactionService {
private final AddressRepository addressRepository; private final AddressRepository addressRepository;
private final StringRedisTemplate stringRedisTemplate;
private Executor excutor; private Executor excutor;
@Override @Override
...@@ -118,13 +130,25 @@ public class TransactionServiceImpl implements TransactionService { ...@@ -118,13 +130,25 @@ public class TransactionServiceImpl implements TransactionService {
List<Address> records = transferAddress(set); List<Address> records = transferAddress(set);
if (!CollectionUtils.isEmpty(records)) { if (!CollectionUtils.isEmpty(records)) {
this.addressRepository.batchInsertOnDuplicateKey(records); this.addressRepository.batchInsertOnDuplicateKey(records);
AccountBalanceTask task = new AccountBalanceTask(set); /* AccountBalanceTask task = new AccountBalanceTask(set);
excutor.execute(task); excutor.execute(task);*/
addressPushRedis(set);
} }
} }
} }
private void addressPushRedis(Set<String> set) {
stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
StringRedisConnection conn = (StringRedisConnection)redisConnection;
set.forEach(o -> conn.sAdd(Constant.ADDRESS_KEY, o));
return null;
}
});
}
/** /**
* 封装账户地址信息 * 封装账户地址信息
* *
...@@ -205,11 +229,12 @@ public class TransactionServiceImpl implements TransactionService { ...@@ -205,11 +229,12 @@ public class TransactionServiceImpl implements TransactionService {
return retList; return retList;
} }
public synchronized void initExcutor() { /*public synchronized void initExcutor() {
if (excutor == null) { if (excutor == null) {
excutor = new Executor(Constant.EXCUTOR_NAME_ACCOUNT, 2); excutor = new Executor(Constant.EXCUTOR_NAME_ACCOUNT, 3);
new AccountBalanceTask();
} }
} }*/
@Override @Override
public Long getBlockMinTime() { public Long getBlockMinTime() {
...@@ -328,11 +353,6 @@ public class TransactionServiceImpl implements TransactionService { ...@@ -328,11 +353,6 @@ public class TransactionServiceImpl implements TransactionService {
return pageInfo; return pageInfo;
} }
@Override
public void init() {
initExcutor();
}
private void census(String date, String startDate, String endDate) { private void census(String date, String startDate, String endDate) {
Long startDateSeconds = DateUtil.getDateFromDateStr(startDate); Long startDateSeconds = DateUtil.getDateFromDateStr(startDate);
Long endDateSeconds = DateUtil.getDateFromDateStr(endDate); Long endDateSeconds = DateUtil.getDateFromDateStr(endDate);
......
...@@ -4,6 +4,12 @@ import java.math.BigDecimal; ...@@ -4,6 +4,12 @@ import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode; import java.math.RoundingMode;
/**
* <core>BigDecimal工具类</core>
*
* @author sky
* @date 2020/11/02
*/
public class BigDecimalUtil { public class BigDecimalUtil {
public static final int SCALE = 32; public static final int SCALE = 32;
......
...@@ -157,33 +157,6 @@ public class DateUtil { ...@@ -157,33 +157,6 @@ public class DateUtil {
return beginningOfDayDate.getTime(); return beginningOfDayDate.getTime();
} }
/**
* 获得当前星期五
*
* @return
*/
public static Date getFriday() {
//获取当前时间
final Calendar calendar = Calendar.getInstance();
switch (calendar.get(Calendar.DAY_OF_WEEK)) {
case Calendar.FRIDAY:
final int hour = calendar.get(Calendar.HOUR_OF_DAY);
final int min = calendar.get(Calendar.MINUTE);
if (hour > HOUR_16_PM || (hour == HOUR_16_PM && min >= MINTUES_10)) {
calendar.add(Calendar.DAY_OF_WEEK, 7);
}
break;
//周6设置
case Calendar.SATURDAY:
calendar.add(Calendar.DAY_OF_WEEK, WEEK_DAY_NUM);
break;
default:
break;
}
calendar.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
return calendar.getTime();
}
/** /**
* date 日期加上或减去几天 * date 日期加上或减去几天
* *
......
...@@ -34,15 +34,7 @@ public class ThreadPoolUtil { ...@@ -34,15 +34,7 @@ public class ThreadPoolUtil {
} }
public static int getCupNum() { public static int getCupNum() {
int cupNum; return Runtime.getRuntime().availableProcessors();
String osName = OSInfo.getOSType().name();
if (osName.equals(Constant.OS_NMAE)) {
cupNum = Runtime.getRuntime().availableProcessors();
} else {
cupNum = Runtime.getRuntime().availableProcessors() * 2;
}
return cupNum;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment