Java

Java

Oracle JDK和Open JDK有什么区别?

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 2028 次浏览 2021-11-30 11:58 来自相关话题

常见的JVM厂商有哪些

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 1999 次浏览 2021-11-29 09:30 来自相关话题

JDK和JVM有啥区别?

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 2106 次浏览 2021-11-09 00:04 来自相关话题

Java程序启动报如下错误

编程 空心菜 回复了问题 1 人关注 1 个回复 6999 次浏览 2020-09-20 00:50 来自相关话题

Java程序处理中文乱码

回复

大数据 chris 发起了问题 1 人关注 0 个回复 3465 次浏览 2017-02-16 23:40 来自相关话题

JAVA日志那点事

编程 chris 发表了文章 0 个评论 4123 次浏览 2016-01-30 22:56 来自相关话题

前言 日志这东西在语言里算基础组件了吧,可惜Java界第三方框架向来比原生组件好用也是事实,缺点是框架太多混战江湖,今天我们就理一理这些日志框架。Java的日志框架分为门面(Facade),或者叫通用日志接口,还有日志实现。日志接口不 ...查看全部


前言


日志这东西在语言里算基础组件了吧,可惜Java界第三方框架向来比原生组件好用也是事实,缺点是框架太多混战江湖,今天我们就理一理这些日志框架。Java的日志框架分为门面(Facade),或者叫通用日志接口,还有日志实现。日志接口不用说,就是定下的日志方法规范,需要具体日志组件去实现的(为啥Sun当年没有定义这东西,看看JPA、JDBC、JMS这些规范定义的多好,或者定义了被抛弃了?)。日志实现就是具体的日志组件了,可以实现日志打印到控制台、文件、数据库等等。下面咱们就具体说说这些东西。


Java日志框架分类


日志门面(Facade)
    []Slf4j[/]
全称Simple Logging Facade for JAVA,真正的日志门面,只提供接口方法,当配合特定的日志实现时,需要引入相应的桥接包
    []Common-logging[/]
Apache提供的一个通用的日志接口,common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库,自己也自带一个功能很弱的日志实现。
差别:[list=1][]Common-logging动态查找日志实现(程序运行时找出日志实现),Slf4j则是静态绑定(编译时找到实现),动态绑定因为依赖ClassLoader寻找和载入日志实现,因此类似于OSGI那种使用独立ClassLoader就会造成无法使用的情况。(呵呵,我一个插件用一个日志框架不行啊,土豪多任性,不过说实话,没用过OSGI,这个我还真没有概念)[/][]Slf4j支持参数化的log字符串,避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),现在你可以直接写:logger.debug(“current user is: {}”, user)。[/]日志实现
    []Log4j[/]
Log4j可能是Java世界里最出名的日志框架了,支持各种目的地各种级别的日志输出,从我刚接触日志就知道这个框架(呵呵,我一直不知道还有JDK Logging这个东西)。最近(也不近了……)Log4j2发布正式版了,没看到谁用,听说也很不错。
    []LogBack[/]
Log4j作者的又一力作(听说是受不了收费文档搞了个开源的,不需要桥接包完美适配Slf4j),个人感觉迄今为止最棒的日志框架了,一直都在用,配置文件够简洁,性能足够好(估计是看自己的Log4j代码差劲了,更新不能解决问题,直接重构了)。
    []JDK Logging 从JDK1.4开始引入,不得不说,你去Google下这个JDK自带的日志组件,并不如Log4j和LogBack之类好用,木有配置文件,日志级别不好理解,想顺心的用估计还得自己封装下,总之大家已经被Log4j惯坏了,JDK的设计并不能被大家认同,唯一的优点我想就是不用引入新额jar包了。[/]


为什么会有门面


看了以上介绍,如果你不是混迹(深陷)Java多年的老手,估计会蒙圈儿了吧,那你肯定会问,要门面干嘛。有了手机就有手机壳、手机膜,框架也一样,门面的作用更多的还是三个字:解耦合。说白了,加入一个项目用了一个日志框架,想换咋整啊?那就一行一行的找日志改呗,想想都是噩梦。于是,门面出来了,门面说啦, 你用我的格式写日志,把日志想写哪儿写哪儿,例如Slf4j-api加上后,想换日志框架,直接把桥接包一换就行。方便极了。
说实话,现在Slf4j基本可以是Java日志的一个标准了,按照它写基本可以实现所有日志实现通吃,但是就有人不服,还写了门面的门面(没错,这个人就是我)。


门面的门面


如果你看过Netty的源码,推荐你看下io.netty.util.internal.logging这个包里内容,会发现Netty又对日志封装了一层,于是灵感来源于此,我也对各大日志框架和门面做了封装。


Hutool-log模块


无论是Netty的日志模块还是我的Hutool-log模块,思想类似于Common Logging,做动态日志实现查找,然后找到相应的日志实现来写入日志,核心代码如下:
/**
* 决定日志实现
* @return 日志实现类
*/
public static Class detectLog(){
List> logClassList = Arrays.asList(
Slf4jLog.class,
Log4jLog.class,
Log4j2Log.class,
ApacheCommonsLog.class,
JdkLog.class
);
for (Class clazz : logClassList) {
try {
clazz.getConstructor(Class.class).newInstance(LogFactory.class).info("Use Log Framework: [{}]", clazz.getSimpleName());
return clazz;
} catch (Error | Exception e) {
continue;
}
}
return JdkLog.class;
}
详细代码可以看这里
说白了非常简单,按顺序实例化相应的日志实现,如果实例化失败(一般是ClassNotFoundException),说明jar不存在,那实例化下一个,通过不停的尝试,最终如果没有引入日志框架,那使用JDK Logging(这个肯定会有的),当然这种方式也和Common-logging存在类似问题,不过不用到跨ClassLoader还是很好用的。
对于JDK Logging,我也做了一些适配,使之可以与Slf4j的日志级别做对应,这样就将各个日志框架差异化降到最小。另一方面,如果你看过我的这篇日志,那你一定了解了我的类名自动识别功能,这样大家在复制类名的时候,就不用修改日志的那一行代码了,在所有类中,日志的初始化只有这一句:
Log log = LogFactory.get();
是不是简洁简洁又简洁?实现方式也很简单:
/**
* @return 获得调用者的日志
*/
public static Log get() {
return getLog(new Exception().getStackTrace()[1].getClassName());
}
通过堆栈引用获得当前类名。
 
作为一个强迫症患者,日志接口我也会定义的非常处女座:
/**
* 日志统一接口
*
* @author Looly
*
*/
public interface Log extends TraceLog, DebugLog, InfoLog, WarnLog, ErrorLog
这样就实现了单一使用,各个日志框架灵活引用的作用了。


分享阅读原文:http://www.xiaoleilu.com/some-thing-about-java-log/


开源分布式数据库Mysql中间件Mycat

开源项目 chris 发表了文章 1 个评论 6903 次浏览 2016-01-09 19:54 来自相关话题

什么是MYCAT []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存 ...查看全部


什么是MYCAT


    []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server[/][]结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品[/][]一个新颖的数据库中间件产品[/]

Mycat特性

    []支持SQL92标准[/][]遵守Mysql原生协议,跨语言,跨数据库的通用中间件代理。[/][]基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster。[/][]支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster[/][]基于Nio实现,有效管理线程,高并发问题。[/][]支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数。[/][]支持2表join,甚至基于caltlet的多表join。[/][]支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。[/][]支持多租户方案。[/][]支持分布式事务(弱xa)。[/][]支持全局序列号,解决分布式下的主键生成问题。[/][]分片规则丰富,插件化开发,易于扩展。[/][]强大的web,命令行监控。[/][]支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。[/][]支持密码加密[/][]支持IP白名单[/][]支持SQL黑名单、sql注入攻击拦截[/][]集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。[/]

Mycat架构

mycat_arch.png

Mycat高可用方案

mysql_ha1.png
mysql_ha2.png
mysql_ha3.png
mycat_ha4.png

Mycat监控

    []支持对Mycat、Mysql性能监控[/][]支持对Mycat的JVM内存提供监控服务[/][]支持对线程的监控[/][]支持对操作系统的CPU、内存、磁盘、网络的监控[/]
mycateye1.png
mycateye2.png

目标

低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。1.5版本架构
mycat2_0.png

长期规划2.0

    []完全实现分布式事务,完全的支持分布式。[/][]通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。[/][]通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。[/][]支持基于zookeeper的主从切换及Mycat集群化管理。[/][]通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。[/][]接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。[/][]通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。[/]


优势


基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。
MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。


Mycat关注


老外都开始关注Mycat了!
catmycat.png


Mycat官方论坛:http://i.mycat.io/forum.php
Mycat Github:https://github.com/MyCATApache
Mycat权威指南第一版_V1.5.1:http://pan.baidu.com/s/1i3SFOpf


Java调用Hbase API访问接口

大数据 空心菜 发表了文章 0 个评论 4254 次浏览 2015-11-08 23:35 来自相关话题

HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,H ...查看全部
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
HBase表一般特点:
    []大:一个表可以有上亿行,上百万列[/][]面向列:面向列(族)的存储和权限控制,列(族)独立检索[/][]稀疏:对于为空(null)的列并不占用存储空间,表可以设计非常稀疏[/]

 
Java 调用 Hbase 非关系型数据库,Hbase 中提供了相关的 Java API 访问接口便于使用,下面是本人综合网络总结的通过 Java 操作 HBase 进行创建、修改、删除表以及查询等。具体封装代码如下:
package yoodb.hbase;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

public class HBaseTest {

// 声明静态配置
static Configuration conf = null;
static final HTablePool tablePool;
static {
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "yoodb");
tablePool = new HTablePool(conf, 15);
}

/*
* 创建表
* @tableName 表名
* @family 列族数组
*/
public static void creatTable(String tableName, String[] family)
throws Exception {
HBaseAdmin admin = new HBaseAdmin(conf);
HTableDescriptor desc = new HTableDescriptor(tableName);
for (int i = 0; i < family.length; i++) {
desc.addFamily(new HColumnDescriptor(family[i]));
}
if (admin.tableExists(tableName)) {
System.out.println("table Exists!");
System.exit(0);
} else {
admin.createTable(desc);
System.out.println("create table Success!");
}
}

/*
* 表添加数据
* @rowKey rowKey
* @tableName 表名
* @column1 第一个列族数组 realname
* @value1 第一个列的值的数组
* @column2 第二个列族数组 address
* @value2 第二个列的值的数组
*/
public static void addTableData(String rowKey, String tableName,String[] column1, String[] value1, String[] column2, String[] value2)
throws IOException {
Put put = new Put(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
HColumnDescriptor[] columnFamilies = table.getTableDescriptor()
.getColumnFamilies();

for (int i = 0; i < columnFamilies.length; i++) {
String familyName = columnFamilies[i].getNameAsString();
if (familyName.equals("realname")) {
for (int j = 0; j < column1.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j]));
}
}
if (familyName.equals("address")) {
for (int j = 0; j < column2.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j]));
}
}
}
table.put(put);
}

/*
* 更新表中的某一列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
* @value 更新后的值
*/
public static void updateTable(String tableName, String rowKey,
String familyName, String columnName, String value)
throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Put put = new Put(Bytes.toBytes(rowKey));
put.add(Bytes.toBytes(familyName), Bytes.toBytes(columnName),Bytes.toBytes(value));
table.put(put);
System.out.println("update table Success!");
}

/*
* 根据rwokey查询
* @rowKey rowKey
* @tableName 表名
*/
public static Result getResult(String tableName, String rowKey)
throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
return result;
}

/*
* 遍历查询hbase表数组
* @tableName 表名
*/
public static void getResultScann(String tableName) throws IOException {
Scan scan = new Scan();
ResultScanner rs = null;
HTable table = (HTable) tablePool.getTable(tableName);
try {
rs = table.getScanner(scan);
for (Result r : rs) {
for (KeyValue kv : r.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("timestamp==>" + kv.getTimestamp());
}
}
} finally {
rs.close();
}
}

/*
* 查询表中的某单一列
* @tableName 表名
* @rowKey rowKey
*/
public static void getResultByColumn(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); // 获取指定列族以及列中修饰符对应列名
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
}

/*
* 查询某列数据的多个版本
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void getResultByVersion(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName));
get.setMaxVersions(5);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}

}

/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void deleteColumn(String tableName, String rowKey,
String falilyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteColumn = new Delete(Bytes.toBytes(rowKey));
deleteColumn.deleteColumns(Bytes.toBytes(falilyName),Bytes.toBytes(columnName));
table.delete(deleteColumn);
System.out.println(falilyName + "==>" + columnName + "is deleted!");
}

/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
*/
public static void deleteAllColumn(String tableName, String rowKey) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteAll = new Delete(Bytes.toBytes(rowKey));
table.delete(deleteAll);
System.out.println("all columns are deleted!");
}

/*
* 删除表
*
* @tableName 表名
*/
public static void deleteTable(String tableName) throws IOException {
HBaseAdmin admin = new HBaseAdmin(conf);
admin.disableTable(tableName);
admin.deleteTable(tableName);
System.out.println(tableName + " is deleted!");
}
}
Java Hbase main函数测试类,具体代码如下:
package com.yoodb;

public class Test {
public static void main(String[] args) throws Exception {
// 创建表
String tableName = "yoodbblog";
String[] family = { "realname","address" };
HBaseTest.creatTable(tableName,family);
// 为表添加数据
String[] column1 = { "title", "author", "content" };
String[] value1 = {"素文宅","yoodb","www.yoodb.com" };
String[] column2 = { "name", "nickname" };
String[] value2 = { "真实名称", "昵称" };
HBaseTest.addTableData("rowkey1","yoodbblog",column1, value1, column2, value2);
// 删除一列
HBaseTest.deleteColumn("yoodbblog", "rowkey1", "realname", "name");
// 删除所有列
HBaseTest.deleteAllColumn("yoodbblog", "rowkey1");
// 删除表
HBaseTest.deleteTable("yoodbblog");
// 查询
HBaseTest.getResult("yoodbblog", "rowkey1");
// 查询某一列的值
HBaseTest.getResultByColumn("yoodbblog", "rowkey1", "realname", "nickname");
// 修改某一列的值
HBaseTest.updateTable("yoodbblog", "rowkey1", "realname", "nickname","假昵称");
// 遍历表数据查询
HBaseTest.getResultScann("yoodbblog");
// 查询某列的多版本
HBaseTest.getResultByVersion("yoodbblog", "rowkey1", "realname", "name");
}
}
分享原文地址
 
 
 

Nexus启动报错

编程 空心菜 回复了问题 2 人关注 1 个回复 5351 次浏览 2015-07-28 00:31 来自相关话题

开源分布式数据库Mysql中间件Mycat

开源项目 chris 发表了文章 1 个评论 6903 次浏览 2016-01-09 19:54 来自相关话题

什么是MYCAT []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存 ...查看全部


什么是MYCAT


    []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server[/][]结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品[/][]一个新颖的数据库中间件产品[/]

Mycat特性

    []支持SQL92标准[/][]遵守Mysql原生协议,跨语言,跨数据库的通用中间件代理。[/][]基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster。[/][]支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster[/][]基于Nio实现,有效管理线程,高并发问题。[/][]支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数。[/][]支持2表join,甚至基于caltlet的多表join。[/][]支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。[/][]支持多租户方案。[/][]支持分布式事务(弱xa)。[/][]支持全局序列号,解决分布式下的主键生成问题。[/][]分片规则丰富,插件化开发,易于扩展。[/][]强大的web,命令行监控。[/][]支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。[/][]支持密码加密[/][]支持IP白名单[/][]支持SQL黑名单、sql注入攻击拦截[/][]集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。[/]

Mycat架构

mycat_arch.png

Mycat高可用方案

mysql_ha1.png
mysql_ha2.png
mysql_ha3.png
mycat_ha4.png

Mycat监控

    []支持对Mycat、Mysql性能监控[/][]支持对Mycat的JVM内存提供监控服务[/][]支持对线程的监控[/][]支持对操作系统的CPU、内存、磁盘、网络的监控[/]
mycateye1.png
mycateye2.png

目标

低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。1.5版本架构
mycat2_0.png

长期规划2.0

    []完全实现分布式事务,完全的支持分布式。[/][]通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。[/][]通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。[/][]支持基于zookeeper的主从切换及Mycat集群化管理。[/][]通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。[/][]接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。[/][]通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。[/]


优势


基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。
MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。


Mycat关注


老外都开始关注Mycat了!
catmycat.png


Mycat官方论坛:http://i.mycat.io/forum.php
Mycat Github:https://github.com/MyCATApache
Mycat权威指南第一版_V1.5.1:http://pan.baidu.com/s/1i3SFOpf


Oracle JDK和Open JDK有什么区别?

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 2028 次浏览 2021-11-30 11:58 来自相关话题

常见的JVM厂商有哪些

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 1999 次浏览 2021-11-29 09:30 来自相关话题

JDK和JVM有啥区别?

回复

编程 OS小编 回复了问题 1 人关注 1 个回复 2106 次浏览 2021-11-09 00:04 来自相关话题

Java程序启动报如下错误

回复

编程 空心菜 回复了问题 1 人关注 1 个回复 6999 次浏览 2020-09-20 00:50 来自相关话题

Java程序处理中文乱码

回复

大数据 chris 发起了问题 1 人关注 0 个回复 3465 次浏览 2017-02-16 23:40 来自相关话题

Nexus启动报错

回复

编程 空心菜 回复了问题 2 人关注 1 个回复 5351 次浏览 2015-07-28 00:31 来自相关话题

JAVA日志那点事

编程 chris 发表了文章 0 个评论 4123 次浏览 2016-01-30 22:56 来自相关话题

前言 日志这东西在语言里算基础组件了吧,可惜Java界第三方框架向来比原生组件好用也是事实,缺点是框架太多混战江湖,今天我们就理一理这些日志框架。Java的日志框架分为门面(Facade),或者叫通用日志接口,还有日志实现。日志接口不 ...查看全部


前言


日志这东西在语言里算基础组件了吧,可惜Java界第三方框架向来比原生组件好用也是事实,缺点是框架太多混战江湖,今天我们就理一理这些日志框架。Java的日志框架分为门面(Facade),或者叫通用日志接口,还有日志实现。日志接口不用说,就是定下的日志方法规范,需要具体日志组件去实现的(为啥Sun当年没有定义这东西,看看JPA、JDBC、JMS这些规范定义的多好,或者定义了被抛弃了?)。日志实现就是具体的日志组件了,可以实现日志打印到控制台、文件、数据库等等。下面咱们就具体说说这些东西。


Java日志框架分类


日志门面(Facade)
    []Slf4j[/]
全称Simple Logging Facade for JAVA,真正的日志门面,只提供接口方法,当配合特定的日志实现时,需要引入相应的桥接包
    []Common-logging[/]
Apache提供的一个通用的日志接口,common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库,自己也自带一个功能很弱的日志实现。
差别:[list=1][]Common-logging动态查找日志实现(程序运行时找出日志实现),Slf4j则是静态绑定(编译时找到实现),动态绑定因为依赖ClassLoader寻找和载入日志实现,因此类似于OSGI那种使用独立ClassLoader就会造成无法使用的情况。(呵呵,我一个插件用一个日志框架不行啊,土豪多任性,不过说实话,没用过OSGI,这个我还真没有概念)[/][]Slf4j支持参数化的log字符串,避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),现在你可以直接写:logger.debug(“current user is: {}”, user)。[/]日志实现
    []Log4j[/]
Log4j可能是Java世界里最出名的日志框架了,支持各种目的地各种级别的日志输出,从我刚接触日志就知道这个框架(呵呵,我一直不知道还有JDK Logging这个东西)。最近(也不近了……)Log4j2发布正式版了,没看到谁用,听说也很不错。
    []LogBack[/]
Log4j作者的又一力作(听说是受不了收费文档搞了个开源的,不需要桥接包完美适配Slf4j),个人感觉迄今为止最棒的日志框架了,一直都在用,配置文件够简洁,性能足够好(估计是看自己的Log4j代码差劲了,更新不能解决问题,直接重构了)。
    []JDK Logging 从JDK1.4开始引入,不得不说,你去Google下这个JDK自带的日志组件,并不如Log4j和LogBack之类好用,木有配置文件,日志级别不好理解,想顺心的用估计还得自己封装下,总之大家已经被Log4j惯坏了,JDK的设计并不能被大家认同,唯一的优点我想就是不用引入新额jar包了。[/]


为什么会有门面


看了以上介绍,如果你不是混迹(深陷)Java多年的老手,估计会蒙圈儿了吧,那你肯定会问,要门面干嘛。有了手机就有手机壳、手机膜,框架也一样,门面的作用更多的还是三个字:解耦合。说白了,加入一个项目用了一个日志框架,想换咋整啊?那就一行一行的找日志改呗,想想都是噩梦。于是,门面出来了,门面说啦, 你用我的格式写日志,把日志想写哪儿写哪儿,例如Slf4j-api加上后,想换日志框架,直接把桥接包一换就行。方便极了。
说实话,现在Slf4j基本可以是Java日志的一个标准了,按照它写基本可以实现所有日志实现通吃,但是就有人不服,还写了门面的门面(没错,这个人就是我)。


门面的门面


如果你看过Netty的源码,推荐你看下io.netty.util.internal.logging这个包里内容,会发现Netty又对日志封装了一层,于是灵感来源于此,我也对各大日志框架和门面做了封装。


Hutool-log模块


无论是Netty的日志模块还是我的Hutool-log模块,思想类似于Common Logging,做动态日志实现查找,然后找到相应的日志实现来写入日志,核心代码如下:
/**
* 决定日志实现
* @return 日志实现类
*/
public static Class detectLog(){
List> logClassList = Arrays.asList(
Slf4jLog.class,
Log4jLog.class,
Log4j2Log.class,
ApacheCommonsLog.class,
JdkLog.class
);
for (Class clazz : logClassList) {
try {
clazz.getConstructor(Class.class).newInstance(LogFactory.class).info("Use Log Framework: [{}]", clazz.getSimpleName());
return clazz;
} catch (Error | Exception e) {
continue;
}
}
return JdkLog.class;
}
详细代码可以看这里
说白了非常简单,按顺序实例化相应的日志实现,如果实例化失败(一般是ClassNotFoundException),说明jar不存在,那实例化下一个,通过不停的尝试,最终如果没有引入日志框架,那使用JDK Logging(这个肯定会有的),当然这种方式也和Common-logging存在类似问题,不过不用到跨ClassLoader还是很好用的。
对于JDK Logging,我也做了一些适配,使之可以与Slf4j的日志级别做对应,这样就将各个日志框架差异化降到最小。另一方面,如果你看过我的这篇日志,那你一定了解了我的类名自动识别功能,这样大家在复制类名的时候,就不用修改日志的那一行代码了,在所有类中,日志的初始化只有这一句:
Log log = LogFactory.get();
是不是简洁简洁又简洁?实现方式也很简单:
/**
* @return 获得调用者的日志
*/
public static Log get() {
return getLog(new Exception().getStackTrace()[1].getClassName());
}
通过堆栈引用获得当前类名。
 
作为一个强迫症患者,日志接口我也会定义的非常处女座:
/**
* 日志统一接口
*
* @author Looly
*
*/
public interface Log extends TraceLog, DebugLog, InfoLog, WarnLog, ErrorLog
这样就实现了单一使用,各个日志框架灵活引用的作用了。


分享阅读原文:http://www.xiaoleilu.com/some-thing-about-java-log/


开源分布式数据库Mysql中间件Mycat

开源项目 chris 发表了文章 1 个评论 6903 次浏览 2016-01-09 19:54 来自相关话题

什么是MYCAT []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存 ...查看全部


什么是MYCAT


    []一个彻底开源的,面向企业应用开发的大数据库集群[/][]支持事务、ACID、可以替代MySQL的加强版数据库[/][]一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群[/][]一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server[/][]结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品[/][]一个新颖的数据库中间件产品[/]

Mycat特性

    []支持SQL92标准[/][]遵守Mysql原生协议,跨语言,跨数据库的通用中间件代理。[/][]基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster。[/][]支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster[/][]基于Nio实现,有效管理线程,高并发问题。[/][]支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数。[/][]支持2表join,甚至基于caltlet的多表join。[/][]支持通过全局表,ER关系的分片策略,实现了高效的多表join查询。[/][]支持多租户方案。[/][]支持分布式事务(弱xa)。[/][]支持全局序列号,解决分布式下的主键生成问题。[/][]分片规则丰富,插件化开发,易于扩展。[/][]强大的web,命令行监控。[/][]支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉。[/][]支持密码加密[/][]支持IP白名单[/][]支持SQL黑名单、sql注入攻击拦截[/][]集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。[/]

Mycat架构

mycat_arch.png

Mycat高可用方案

mysql_ha1.png
mysql_ha2.png
mysql_ha3.png
mycat_ha4.png

Mycat监控

    []支持对Mycat、Mysql性能监控[/][]支持对Mycat的JVM内存提供监控服务[/][]支持对线程的监控[/][]支持对操作系统的CPU、内存、磁盘、网络的监控[/]
mycateye1.png
mycateye2.png

目标

低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。1.5版本架构
mycat2_0.png

长期规划2.0

    []完全实现分布式事务,完全的支持分布式。[/][]通过Mycat web(eye)完成可视化配置,及智能监控,自动运维。[/][]通过mysql 本地节点,完整的解决数据扩容难度,实现自动扩容机制,解决扩容难点。[/][]支持基于zookeeper的主从切换及Mycat集群化管理。[/][]通过Mycat Balance 替代第三方的Haproxy,LVS等第三方高可用,完整的兼容Mycat集群节点的动态上下线。[/][]接入Spark等第三方工具,解决数据分析及大数据聚合的业务场景。[/][]通过Mycat智能优化,分析分片热点,提供合理的分片建议,索引建议,及数据切分实时业务建议。[/]


优势


基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点,站在巨人的肩膀上,我们能看到更远。业界优秀的开源项目和创新思路被广泛融入到MYCAT的基因中,使得MYCAT在很多方面都领先于目前其他一些同类的开源项目,甚至超越某些商业产品。
MYCAT背后有一支强大的技术团队,其参与者都是5年以上资深软件工程师、架构师、DBA等,优秀的技术团队保证了MYCAT的产品质量。
MYCAT并不依托于任何一个商业公司,因此不像某些开源项目,将一些重要的特性封闭在其商业产品中,使得开源项目成了一个摆设。


Mycat关注


老外都开始关注Mycat了!
catmycat.png


Mycat官方论坛:http://i.mycat.io/forum.php
Mycat Github:https://github.com/MyCATApache
Mycat权威指南第一版_V1.5.1:http://pan.baidu.com/s/1i3SFOpf


Java调用Hbase API访问接口

大数据 空心菜 发表了文章 0 个评论 4254 次浏览 2015-11-08 23:35 来自相关话题

HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,H ...查看全部
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
HBase表一般特点:
    []大:一个表可以有上亿行,上百万列[/][]面向列:面向列(族)的存储和权限控制,列(族)独立检索[/][]稀疏:对于为空(null)的列并不占用存储空间,表可以设计非常稀疏[/]

 
Java 调用 Hbase 非关系型数据库,Hbase 中提供了相关的 Java API 访问接口便于使用,下面是本人综合网络总结的通过 Java 操作 HBase 进行创建、修改、删除表以及查询等。具体封装代码如下:
package yoodb.hbase;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

public class HBaseTest {

// 声明静态配置
static Configuration conf = null;
static final HTablePool tablePool;
static {
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "yoodb");
tablePool = new HTablePool(conf, 15);
}

/*
* 创建表
* @tableName 表名
* @family 列族数组
*/
public static void creatTable(String tableName, String[] family)
throws Exception {
HBaseAdmin admin = new HBaseAdmin(conf);
HTableDescriptor desc = new HTableDescriptor(tableName);
for (int i = 0; i < family.length; i++) {
desc.addFamily(new HColumnDescriptor(family[i]));
}
if (admin.tableExists(tableName)) {
System.out.println("table Exists!");
System.exit(0);
} else {
admin.createTable(desc);
System.out.println("create table Success!");
}
}

/*
* 表添加数据
* @rowKey rowKey
* @tableName 表名
* @column1 第一个列族数组 realname
* @value1 第一个列的值的数组
* @column2 第二个列族数组 address
* @value2 第二个列的值的数组
*/
public static void addTableData(String rowKey, String tableName,String[] column1, String[] value1, String[] column2, String[] value2)
throws IOException {
Put put = new Put(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
HColumnDescriptor[] columnFamilies = table.getTableDescriptor()
.getColumnFamilies();

for (int i = 0; i < columnFamilies.length; i++) {
String familyName = columnFamilies[i].getNameAsString();
if (familyName.equals("realname")) {
for (int j = 0; j < column1.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j]));
}
}
if (familyName.equals("address")) {
for (int j = 0; j < column2.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j]));
}
}
}
table.put(put);
}

/*
* 更新表中的某一列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
* @value 更新后的值
*/
public static void updateTable(String tableName, String rowKey,
String familyName, String columnName, String value)
throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Put put = new Put(Bytes.toBytes(rowKey));
put.add(Bytes.toBytes(familyName), Bytes.toBytes(columnName),Bytes.toBytes(value));
table.put(put);
System.out.println("update table Success!");
}

/*
* 根据rwokey查询
* @rowKey rowKey
* @tableName 表名
*/
public static Result getResult(String tableName, String rowKey)
throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
return result;
}

/*
* 遍历查询hbase表数组
* @tableName 表名
*/
public static void getResultScann(String tableName) throws IOException {
Scan scan = new Scan();
ResultScanner rs = null;
HTable table = (HTable) tablePool.getTable(tableName);
try {
rs = table.getScanner(scan);
for (Result r : rs) {
for (KeyValue kv : r.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("timestamp==>" + kv.getTimestamp());
}
}
} finally {
rs.close();
}
}

/*
* 查询表中的某单一列
* @tableName 表名
* @rowKey rowKey
*/
public static void getResultByColumn(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); // 获取指定列族以及列中修饰符对应列名
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
}

/*
* 查询某列数据的多个版本
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void getResultByVersion(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName));
get.setMaxVersions(5);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}

}

/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void deleteColumn(String tableName, String rowKey,
String falilyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteColumn = new Delete(Bytes.toBytes(rowKey));
deleteColumn.deleteColumns(Bytes.toBytes(falilyName),Bytes.toBytes(columnName));
table.delete(deleteColumn);
System.out.println(falilyName + "==>" + columnName + "is deleted!");
}

/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
*/
public static void deleteAllColumn(String tableName, String rowKey) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteAll = new Delete(Bytes.toBytes(rowKey));
table.delete(deleteAll);
System.out.println("all columns are deleted!");
}

/*
* 删除表
*
* @tableName 表名
*/
public static void deleteTable(String tableName) throws IOException {
HBaseAdmin admin = new HBaseAdmin(conf);
admin.disableTable(tableName);
admin.deleteTable(tableName);
System.out.println(tableName + " is deleted!");
}
}
Java Hbase main函数测试类,具体代码如下:
package com.yoodb;

public class Test {
public static void main(String[] args) throws Exception {
// 创建表
String tableName = "yoodbblog";
String[] family = { "realname","address" };
HBaseTest.creatTable(tableName,family);
// 为表添加数据
String[] column1 = { "title", "author", "content" };
String[] value1 = {"素文宅","yoodb","www.yoodb.com" };
String[] column2 = { "name", "nickname" };
String[] value2 = { "真实名称", "昵称" };
HBaseTest.addTableData("rowkey1","yoodbblog",column1, value1, column2, value2);
// 删除一列
HBaseTest.deleteColumn("yoodbblog", "rowkey1", "realname", "name");
// 删除所有列
HBaseTest.deleteAllColumn("yoodbblog", "rowkey1");
// 删除表
HBaseTest.deleteTable("yoodbblog");
// 查询
HBaseTest.getResult("yoodbblog", "rowkey1");
// 查询某一列的值
HBaseTest.getResultByColumn("yoodbblog", "rowkey1", "realname", "nickname");
// 修改某一列的值
HBaseTest.updateTable("yoodbblog", "rowkey1", "realname", "nickname","假昵称");
// 遍历表数据查询
HBaseTest.getResultScann("yoodbblog");
// 查询某列的多版本
HBaseTest.getResultByVersion("yoodbblog", "rowkey1", "realname", "name");
}
}
分享原文地址