分类
Java

SpringBoot + Sharding-JDBC3.x配置

sharding:
  jdbc:
    datasource:
      names: ds0, ds1 # 数据源名称,多数据源以逗号分隔
      ds0:
        type: # 数据库连接池类名称
        driver-class-name: com.mysql.cj.jdbc.Driver # 数据库驱动类名
        url: jdbc:mysql://localhost:3306/ds0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=utf8 # 数据库url连接
        username: root # 数据库用户名
        password: root # 数据库密码
        xxx: #数据库连接池的其它属性
      ds1:
        type:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/ds1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=utf8
          username: root
          password: root
    config:
      props:
        sql:
          show: true # 是否开启SQL显示,默认值: false
          executor:
            size: # 工作线程数量,默认值: CPU核数
          check:
            table:
              metadata:
                enabled: # 是否在启动时检查分表元数据一致性,默认值: false
      sharding:
        binding-tables: # 绑定表规则列表1
        broadcast-tables: #广播表规则列表1
        default-data-source-name: # 未配置分片规则的表将通过默认数据源定位
        default-database-strategy: # 默认数据库分片策略,同分库策略
          inline:
            sharding-column: user_id
            algorithm-expression: ds$->{user_id % 2}
        default-table-strategy: # 默认表分片策略,同分表策略
        default-key-generator-class-name: # 默认自增列值生成器类名称,缺省使用io.shardingsphere.core.keygen.DefaultKeyGenerator。该类需实现KeyGenerator接口并提供无参数的构造器
        tables: # 数据分片
          t_order:
            # 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点。用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况
            actual-data-nodes: ds$->{0..1}.t_order$->{0..1}
            database-strategy: # 分库策略 4选一
              standard: # 用于单分片键的标准分片场景
                sharding-column: # 分片列名称
                precise-algorithm-class-name: # 精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                range-algorithm-class-name: # 范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
              complex: # 用于多分片键的复合分片场景
                sharding-columns: # 分片列名称,多个列以逗号分隔
                algorithm-class-name: # 复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器
              inline: # 行表达式分片策略
                sharding-column: # 分片列名称
                algorithm-expression: # 分片算法行表达式,需符合groovy语法
              hint: # Hint分片策略
                algorithm-class-name: # Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器
            table-strategy: # 分表策略
              standard: # 用于单分片键的标准分片场景
                sharding-column: # 分片列名称
                precise-algorithm-class-name: # 精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                range-algorithm-class-name: # 范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
                complex: # 用于多分片键的复合分片场景
                  sharding-columns: # 分片列名称,多个列以逗号分隔
                  algorithm-class-name: # 复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器
                inline: # 行表达式分片策略
                  sharding-column: # 分片列名称
                  algorithm-expression: # 分片算法行表达式,需符合groovy语法
                hint: # Hint分片策略
                  algorithm-class-name: # Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器
            key-generator-column-name: # 自增列名称,缺省表示不使用自增主键生成器
            key-generator-class-name: # 自增列值生成器类名称,缺省表示使用默认自增列值生成器。该类需提供无参数的构造器
            logic-index: # 逻辑索引名称,对于分表的Oracle/PostgreSQL数据库中DROP INDEX XXX语句,需要通过配置逻辑索引名称定位所执行SQL的真实分表
          t_order_item:
            # 由数据源名 + 表名组成,以小数点分隔。多个表以逗号分隔,支持inline表达式。缺省表示使用已知数据源与逻辑表名称生成数据节点。用于广播表(即每个库中都需要一个同样的表用于关联查询,多为字典表)或只分库不分表且所有库的表结构完全一致的情况
            actual-data-nodes: ds$->{0..1}.t_order$->{0..1}
            database-strategy: # 分库策略
              standard: # 用于单分片键的标准分片场景
                sharding-column: # 分片列名称
                precise-algorithm-class-name: # 精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                range-algorithm-class-name: # 范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
              complex: # 用于多分片键的复合分片场景
                sharding-columns: # 分片列名称,多个列以逗号分隔
                algorithm-class-name: # 复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器
              inline: # 行表达式分片策略
                sharding-column: # 分片列名称
                algorithm-expression: # 分片算法行表达式,需符合groovy语法
              hint: # Hint分片策略
                algorithm-class-name: # Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器
            table-strategy: # 分表策略
              standard: # 用于单分片键的标准分片场景
                sharding-column: # 分片列名称
                precise-algorithm-class-name: # 精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
                range-algorithm-class-name: # 范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
                complex: # 用于多分片键的复合分片场景
                  sharding-columns: # 分片列名称,多个列以逗号分隔
                  algorithm-class-name: # 复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器
                inline: # 行表达式分片策略
                  sharding-column: # 分片列名称
                  algorithm-expression: # 分片算法行表达式,需符合groovy语法
                hint: # Hint分片策略
                  algorithm-class-name: # Hint分片算法类名称。该类需实现HintShardingAlgorithm接口并提供无参数的构造器
        master-slave-rules: # 读写分离
          ds0: # 主从数据源的名称
            master-data-source-name: # 主库数据源名称
            slave-data-source-names: # 从库数据源名称列表
            load-balance-algorithm-class-name: # 从库负载均衡算法类名称。该类需实现MasterSlaveLoadBalanceAlgorithm接口且提供无参数构造器
            load-balance-algorithm-type: # 从库负载均衡算法类型,可选值:ROUND_ROBIN,RANDOM。若`load-balance-algorithm-class-name`存在则忽略该配置
          ds1: # 主从数据源的名称
            master-data-source-name: # 主库数据源名称
            slave-data-source-names: # 从库数据源名称列表
            load-balance-algorithm-class-name: # 从库负载均衡算法类名称。该类需实现MasterSlaveLoadBalanceAlgorithm接口且提供无参数构造器
            load-balance-algorithm-type: # 从库负载均衡算法类型,可选值:ROUND_ROBIN,RANDOM。若`load-balance-algorithm-class-name`存在则忽略该配置
          map:
            key1: # 用户自定义配置 Key1为用户填
            key2: # 用户自定义配置
        orchestration: # 数据治理
          name: # 数据治理实例名称
          overwrite: # 本地配置是否覆盖注册中心配置。如果可覆盖,每次启动都以本地配置为准
          registry:
            server-lists: # 连接注册中心服务器的列表。包括IP地址和端口号。多个地址用逗号分隔。如: host1:2181,host2:2181
            namespace: # 注册中心的命名空间
            digest: # 连接注册中心的权限令牌。缺省为不需要权限验证
            operation-timeout-milliseconds: # 操作超时的毫秒数,默认500毫秒
            max-retries: # 连接失败后的最大重试次数,默认3次
            retry-interval-milliseconds: # 重试间隔毫秒数,默认500毫秒
            time-to-live-seconds: # 临时节点存活秒数,默认60秒
分类
Java 大数据 笔记

初识Sharding-JDBC 4.0

昨天(1月14日)ShardingSphere 4.0.0 发布。发布说明:ShardingSphere 4.0.0 发布,ShardingSphere 四周年贺礼

基于4.0版简单写了个Demo,主要是测试数据分片,读写分离,数据脱敏。

数据分片

数据分片应该是Sharding-JDBC最核心的功能。主要是根据自定义规则解析SQL,把数据放到不同库表中,从不同库表中查询,组装数据并返回最终结果。这种水平分片的方
式相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。数
据分片的核心概念。

分类
Java 笔记

JVM 性能调优监控工具

现实企业级Java应用开发、维护中,有时候我们会碰到下面这些问题:

  • OutOfMemoryError,内存不足
  • 内存泄露
  • 线程死锁
  • 锁争用(Lock Contention)
  • Java进程消耗CPU过高
  • ……

这些问题在日常开发、维护中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。本文将对一些常用的JVM性能调优监控工具进行介绍,希望能起抛砖引玉之用。

分类
Java

使用 Java 持久化 API

对应用开发者来说,Java 持久化 APIJava Persistence API(JPA)是一项重要的 java 功能,需要透彻理解。它为 Java 开发人员定义了如何将对象的方法调用转换为访问、持久化及管理存储在 NoSQL 和关系型数据库中的数据的方案。

本文通过构建自行车借贷服务的教程示例来详细研究 JPA。此示例会使用 Spring Boot 框架、MongoDB 数据库(已经不开源)和 Maven 包管理来构建一个大型应用程序,并且构建一个创建、读取、更新和删除(CRUD)层。这儿我选择 NetBeans 11 作为我的 IDE。

此教程仅从开源的角度来介绍 Java 持久化 API 的工作原理,不涉及其作为工具的使用说明。这全是关于编写应用程序模式的学习,但对于理解具体的软件实现也很益处。可以从我的 GitHub 仓库来获取相关代码。

Java: 不仅仅是“豆子”

Java 是一门面向对象的编程语言,自 1996 年发布第一版 Java 开发工具(JDK)起,已经变化了很多很多。要了解其各种发展及其虚拟机本身就是一堂历史课。简而言之,和 Linux 内核很相似,自发布以来,该语言已经向多个方向分支发展。有对社区免费的标准版本、有针对企业的企业版本及由多家供应商提供的开源替代品。主要版本每六个月发布一次,其功能往往差异很大,所以确认选用版本前得先做些研究。

总而言之,Java 的历史很悠久。本教程重点介绍 Java 11 的开源实现 JDK 11。因其是仍然有效的长期支持版本之一。

  • Spring Boot 是由 Pivotal 公司开发的大型 Spring 框架的一个模块。Spring 是 Java 开发中一个非常流行的框架。它支持各种框架和配置,也为 WEB 应用程序及安全提供了保障。Spring Boot 为快速构建各种类型的 Java 项目提供了基本的配置。本教程使用 Spring Boot 来快速编写控制台应用程序并针对数据库编写测试用例。
  • Maven 是由 Apache 开发的项目/包管理工具。Maven 通过 POM.xml 文件来管理包及其依赖项。如果你使用过 NPM 的话,可能会非常熟悉包管理器的功能。此外 Maven 也用来进行项目构建及生成功能报告。
  • Lombok 是一个库,它通过在对象文件里面添加注解来自动创建 getters/setters 方法。像 C# 这些语言已经实现了此功能,Lombok 只是把此功能引入 Java 语言而已。
  • NetBeans 是一款很流行的开源 IDE,专门用于 Java 开发。它的许多工具都随着 Java SE 和 EE 的版本更新而更新。

我们会用这组工具为一个虚构自行车商店创建一个简单的应用程序。会实现对 Customer 和 Bike 对象集合的的插入操作。

分类
Java

Spring Cloud 2020 年路线图

Spring Cloud 开发团队昨日公布了 Spring Cloud 2020 年的路线图,并对 Spring Cloud Greenwich 和 Hoxton 的生命周期进行了一些讲解。

Spring Cloud Ilford

开发团队称 Spring Cloud Ilford 将是下一个主要版本,这也将是自 Spring Cloud Finchley 发布以来的第一个主要版本。此版本将提供对 Spring Boot 2.x 和 Spring Framework 5.x 的支持。通过使 Ilford 成为主要版本,开发团队将能够删除进入维护模式(maintenance mode)的模块,并兑现今年早些时候宣布的简化新版本的承诺。此外,团队成员还会对一些 API 进行重构,这可能会引入重大变更。

Spring Cloud Ilford 将在 2020 年第四季度的某个时候随 Spring Framework 5.3 和 Spring Boot 2.4 一起发布。

分类
Java

利用 Kafka 设置可靠的高性能分布式消息传递基础架构

世界已经迈进”移动”时代,现在应用程序必须能够实时提供数据,这不仅包括数据库表中存储的重要最终结果,还包括用户使用应用程序时执行的所有操作。任何可用信息,例如,用户点击量、日志数据或传感器数据都可用于改善用户体验、生成报告、向机器学习系统提供数据,等等。现如今,开发者必须关注基于实时事件流的系统。

下图展示了基于事件流处理的架构示例。

Apache Kafka 已成为构建基于事件的高度可扩展系统的首选解决方案。Kafka 可为事件流平台提供快速升级换代的功能,以供开发者在现代化业务解决方案中使用。然而,开发者通常需要将现有 Java EE 业务解决方案(基于 IBM MQ 或 IBM WebSphere Application Platform 之类的技术而构建的)集成到这些新的事件流架构中。

考虑以下示例: 某个网上商店拥有一个移动应用程序,该应用程序使用 Kafka 向企业 Java 中实施的分布式支付系统发送支付请求数据。该解决方案必须绝对保证一次性完成支付请求的处理(避免多次向买家收费)。但是,在分布式系统中,故障是不可避免的,因此该解决方案需要采用稳妥的方式来处理故障。

分类
Java 编程

JAVA程序通过代理访问网络

指定 Java 程序的代理服务器地址和端口有两种指定方式:

1.通过 命令行参数 指定

如果只需要考虑代理 HTTP 协议请求,只需添加如下命令行参数:

-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=1080

想要 HTTP 和 HTTPS 协议的请求都通过代理访问网络,可以追加上:

-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=1080

最终填写的值为:

-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=1080 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=1080

2.在程序中使用System.setProperty(String, String)

同样很简单,这里直接上代码:

String proxyHost = "127.0.0.1";
String proxyPort = "1080";

System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", proxyPort);

// 对https也开启代理
System.setProperty("https.proxyHost", proxyHost);
System.setProperty("https.proxyPort", proxyPort);

推荐使用第一种方案,通过VM Option 的方式,对代码没有任何侵入,绿色环保。

分类
Java 笔记 编程

Feign设置header无效

把原生Http Connection改为使用Feign请求调用外部接口,在方法上添加注解:

@PostMapping("{接口url}")
@Headers({"Content-Type: application/json"})

返回:

看来用@Headers设置的Content-Type没有生效。@Headers是Feign自带的注册,而@PostMapping是Spring MVC的注解。在@PostMapping中也有header属性,于是改为:

@PostMapping(value = "{接口url}", headers = {"Content-Type: application/json"})

问题依旧。

分类
Java

Mybatis Generator 1.4.0 发布

Mybatis Generator是一个自动代码工具,此版本相较于旧版本有很多重要的更新。

Mybatis Generator目前有5种运行模式,分别为:MyBatis3DynamicSql、MyBatis3Kotlin、MyBatis3、MyBatis3Simple、MyBatis3DynamicSqlV1。

<context id="MysqlTables" targetRuntime="MyBatis3DynamicSql" defaultModelType="flat">
 <!-- 省略中间 -->
</context>

1、MyBatis3、MyBatis3Simple是比较老的模式,通常生成mapper接口、model实体和XML文件(当javaClientGenerator type为 ANNOTATEDMAPPER 时不生成XML)。这两种模式生成的文件只需要依赖Mybatis3即可正常工作,但是对于很多操作不支持。如果想要使用数据库函数或者多表联合查询,这种模式下是不支持的,需要写额外的SQL。

2、MyBatis3DynamicSqlV1是比较新的模式。除了需要依赖Mybatis3以外,还需要mybatis-dynamic-sql才能正常工作。相比上面的老模式,这种模式更加方便。

分类
Java 编程

再见Mybatis Generator,你好Mybatis Plus

很久以前就使用Mybatis开发,Mybatis官方出品的Mybatis Generator能够自动生成Mapper和XML映射文件,提供基本的CRUD操作方法。

Mybatis Generator生成Entity同时可以生成Example,做为条件对像查询,避免写SQL。Example会跟据字段生成and,or,like等方法,也有eq,lt,gt,le,lt等比较方法和order by排序。

Mybatis Generator生成的SQL语句不提供数据库分页和排序,很多功能实现起来需要插件。我以前也写过分页插件,自定义封装了一个DaoService。在分页插件中增加了like查询,传入Entity跟据字段是否为空做条件用and查询。因为大多情况都是and查询,封装后很多操作不需要写SQL,也不需要用代码判断条件,提高了开发效率。

最近的项目用上了Mybatis Plus,虽说是第一次用,但很多东西与Mybatis Generator相似。Mybatis plus作者说,只在Mybatis上做增强,不做修改。因为这点我很钟意这个框架。