刘召考的博客 http://www.liuzk.com _一个勤勤恳恳却又不安于敲代码的程序猿 Tue, 18 Feb 2020 12:16:56 +0000 zh-CN hourly 1 https://wordpress.org/?v=4.2.26 Spring Boot热部署的几种方式 http://www.liuzk.com/471.html http://www.liuzk.com/471.html#comments Tue, 18 Feb 2020 12:12:08 +0000 http://www.liuzk.com/?p=471 1、模板热部署

在 Spring Boot 中,添加了对各种模板框架的支持,当然也就有对模板的配置,模板引擎的页面默认是开启缓存的,如果修改了页面的内容,则刷新页面是得不到修改后的页面的,因此我们可以在application.properties中关闭模版引擎的缓存,如下:

Thymeleaf的配置:

spring.thymeleaf.cache=false

FreeMarker的配置:

spring.freemarker.cache=false

Groovy的配置:

spring.groovy.template.cache=false

Velocity的配置:

spring.velocity.cache=false

2、使用IDE的调试模式Debug实现热部署

此种方式为最简单最快速的一种热部署方式,Idea、Eclipse都有,运行系统时使用Debug模式,无需装任何插件即可,但是无法对配置文件,方法名称改变,增加类及方法进行热部署,使用范围有限。

 

3、spring-boot-devtools

在 Spring Boot 项目中添加 spring-boot-devtools依赖即可实现页面和代码的热部署。

如下:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
</dependency>

此种方式的特点是作用范围广,系统的任何变动包括配置文件修改、方法名称变化都能覆盖。

但是缺点也非常明显,它是采用文件变化后重启的策略来实现了,主要是节省了我们手动点击重启的时间,提高了实效性,在体验上会稍差。

spring-boot-devtools 默认关闭了模版缓存,如果使用这种方式不用单独配置关闭模版缓存。

4、Spring Loaded

此种方式与Debug模式类似,适用范围有限,但是不依赖于Debug模式启动,通过Spring Loaded库文件启动,即可在正常模式下进行实时热部署。此种需要在 run confrgration 中进行配置。

5、JRebel

Jrebel是Java开发最好的热部署工具,对 Spring Boot 提供了极佳的支持,JRebel为收费软件,试用期14天,可直接通过插件安装。

 

 

 

 

 

转载请注明:刘召考的博客 » Spring Boot热部署的几种方式

]]>
http://www.liuzk.com/471.html/feed 0
零基础学SpringBoot—HelloWorld http://www.liuzk.com/462.html http://www.liuzk.com/462.html#comments Mon, 13 Jan 2020 12:12:16 +0000 http://www.liuzk.com/?p=462 什么是 Spring Boot?

Spring Boot 是由 Pivotal 团队提供的全新框架。Spring Boot 是所有基于 Spring Framework 5.0 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。

设计目的: 用来简化新 Spring 应用的初始搭建以及开发过程。

从最根本上来讲,Spring Boot 就是一些库的集合,它能够被任意项目的构建系统所使用。它使用 “习惯优于配置” (项目中存在大量的配置,此外还内置一个习惯性的配置)的理念让你的项目快速运行起来。用大佬的话来理解,就是 spring boot 其实不是什么新的框架,它默认配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,spring boot 整合了所有的框架,总结一下及几点:

(1)为所有 Spring 开发提供一个更快更广泛的入门体验。

(2)零配置。无冗余代码生成和XML 强制配置,遵循“约定大于配置” 。

(3)集成了大量常用的第三方库的配置, Spring Boot 应用为这些第三方库提供了几乎可以零配置的开箱即用的能力。

(4)提供一系列大型项目常用的非功能性特征,如嵌入式服务器、安全性、度量、运行状况检查、外部化配置等。

(5)Spring Boot 不是Spring 的替代者,Spring 框架是通过 IOC 机制来管理 Bean 的。Spring Boot 依赖 Spring 框架来管理对象的依赖。Spring Boot 并不是Spring 的精简版本,而是为使用 Spring 做好各种产品级准备

Spring Boot 在应用中的角色

Spring Boot 是基于 Spring Framework 来构建的,Spring Framework 是一种 J2EE 的框架(什么是 J2EE?)
Spring Boot 是一种快速构建 Spring 应用
Spring Cloud 是构建 Spring Boot 分布式环境,也就是常说的云应用
Spring Boot 中流砥柱,承上启下

环境:

IDEA、JDK1.8、Maaven

Coding开始:

1、搭建一个Maven工程,结构如下:

20200113195437

2、添加Pom依赖和项目构建配置

<?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>

    <groupId>com.zhuanzhuan.qc</groupId>
    <artifactId>qctest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.encoding>UTF-8</project.encoding>
        <jdk.version>1.8</jdk.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <distributionManagement>
        <repository>
            <id>releases</id>
            <name>Internal Releases</name>
            <url>http://nexus.zhuanspirit.com/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>Snapshots</id>
            <name>Internal Snapshots</name>
            <url>http://nexus.zhuanspirit.com/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                    <encoding>${project.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

***这是基于我公司的Maven仓库搭建的,可以依据需要改成自己公司的或者其他的maven仓库

 

3、配置文件:application.properties,Spring boot崇尚简约,所以基本上没有配置文件,这是唯一的一个必须的配置文件了。此处我只配置了Web项目启动的端口。

server.port=8081

其他更详细的配置参考:http://www.liuzk.com/464.html

4、Controller

完全是用注解配置URL,参数等

@RestController
@RequestMapping("/")
public class IndexController {

    @RequestMapping("pageTest")
    public ModelAndView pageTest(@PathVariable("id") Long id,
                              @PathVariable("name") String name,
                              HttpServletRequest reuqest, Model model) {
        return new ModelAndView("pageTest");
    }

    @RequestMapping("jsonTest")
    public String jsonTest() {
        return "{\n" +
                "\t\"success\":true,\n" +
                "\t\"code\":0,\n" +
                "\t\"msg\":\"\",\n" +
                "\t\"rows\":1,\n" +
                "\t\"data\":{[}\n"+
                "}}";
    }

}

 

5、MainClass 开始运行

Spring Boot提供了一个很方便的运行步骤,自己写个Main函数就可以启动整个项目,不得不说,太方便了。

package com.zhuanzhuan.qc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author LiuZhaoKao
 * @Description
 * @date 2020/1/13 19:29
 */
@SpringBootApplication(
        scanBasePackages={"com.zhuanzhuan.qc"}
)
public class MainClazz {
    public static void main(String[] args) {
        SpringApplication.run(MainClazz.class, args);
    }
}运行

运行当前类,当出现“Started MainClazz in 1.646 seconds (JVM running for 2.795)”信息时,表示运行成功。

20200113200842

现在可以在浏览器里访问URL了。

输入:http://127.0.0.1:8081/jsonTest/

测试一下吧。

 

 

转载请注明:刘召考的博客 » 零基础学SpringBoot—HelloWorld

]]>
http://www.liuzk.com/462.html/feed 0
Spring Boot application.properties 配置参数详情 http://www.liuzk.com/464.html http://www.liuzk.com/464.html#comments Mon, 13 Jan 2020 12:03:42 +0000 http://www.liuzk.com/?p=464 multipart

multipart.enabled 开启上传支持(默认:true)

multipart.file-size-threshold: 大于该值的文件会被写到磁盘上

multipart.location 上传文件存放位置

multipart.max-file-size最大文件大小

multipart.max-request-size 最大请求大小

server

server.address 服务器地址

server.port 服务器端口

server.context-parameters.[param name] 设置 servlet 上下文参数

server.context-path 应用上下文路径

Jsp-servelt

server.jsp-servelt.class-name 针对jsp 使用的 Servlet 类名(默认:org.apache.jasper.servlet.JspServlet)

server.jsp-servlet.registered JspServelt 是否要注册到内嵌的 Servlet 容器里(默认 true)

server.jsp-servlet.init-parameters[param name] 设置 Jsp Servlet 初始化参数

server.servlet-path主分发器 Servlet 的路径(默认:/)

Session

server.session.cookie.domain 回话 Cookie 的域

server.session.cookie.comment Cookie 注释

server.session.cookie.max-age Cookie 最大保存时间(单位 s)

server.session.cookie.name Cookie 名称

server.session.cookie.timeout 超时时间

tomcat

server.tomcat.accesslog.directory 创建日志文件的目录

server.tomcat.accesslog.enabled 是否开启访问日志(默认:false)

server.tomcat.accesslog.pattern 访问日志的格式(默认:common)

server.tomcat.accesslog.prefix日志名前缀(默认:access_log)

server.tomcat.accesslog.suffix 日志名后缀(默认:.log)

server.tomcat.max-http-header-sizeHttp 消息头最大字节数(默认:0)

server.tomcat.uri-encoding 用来解码 URI 的字符编码

Cache

spring.cache.cache-names 如果底层缓存管理器支持缓存名的话,可以在这里指定要创建的缓存名列表,用逗号分 隔。通常这会禁用运行时创建其他额外缓存的能力。

spring.cache.config 用来初始化 EhCache 的配置文件位置

spring.cache.guava.spec 用来创建缓存 Spec

spring.cache.hazelcast.config 用来初始化 Hazeleast 的配置文件位置

spring.cache.infinispan.config 用来初始化 Infinispan 配置文件位置

spring.cache.jcache.config用来初始化缓存管理器的配置文件的位置,配置文件依赖于底层的缓存实现

spring.cache.jcache.provider CachingProvider 实现的全限定类名,用来获取 JSR-107 兼容的缓存管理器,仅在 Classpath 里有不只一个 JSR-107 实现时才需要这个属性。

spring.cache.type 缓存类型,默认根据环境自动检测

Data

spring.data.jpa.repositories.enabled 开启 JPA 仓库(默认:true)

spring.data.mongodb.authentication-database 身份认证数据库名

spring.data.mongodb.database 数据库名

spring.data.mongodb.field-naming-strategy 要使用的 FieldNamingStrategy 的全限定名。

spring.data.mongodb.grid.fs.database GridFS 数据库名称

spring.data.mongodb.host MongoDB 服务器地址

spring.data.mongodb.username MongoDB 账号

spring.data.mongodb.passwordMongoDB 密码

spring.data.mongodb.port 端口号

spring.data.mongodb.repositories.enabled 开启 Mongo 仓库(默认值:true)

spring.data.mongodb.uri Mongo 数据库 URI。设置了该属性后就主机和端口号会被忽略。(默认值: mongodb:// localhost/test)

spring.data.rest.base-path 用于发布仓库资源的基本路径

spring.data.rest.default-page-size 分页数据的默认页大小(默认:20)

spring.data.rest.limit-param-name用于标识一次返回多少记录的 URL 查询字符串参数名。(默认值: size )

spring.data.rest.max-page-sieze: 最大分页大小(默认:1000)

spring.data.rest.page-param-name URL 查询字符串参数的名称,用来标识返回哪一页。(默认值: page )

spring.data.rest.return-body-on-create 在创建实体后是否返回一个响应体(默认:false)

spring.data.rest.return-body-on-update 在更新实体后是否返回一个响应体(默认:false)

spring.data.rest.sort-param-name URL 查询字符串参数的名称,用来表示结果排序的方向(默认:name)

spring.data.solr.host Solr 的主机地址。如果设置了 zk-host 则忽略该属性。(默认值: http://127.0.0.1: 8983/solr )

spring.data.solr.repositories.enabled 开启 solr 仓库(默认:true)

spring.data.solr.zk-host zk 主机地址,格式为 “主机 – 端口”

spring.datasource.allow-pool-suspension 是否允许池暂停(pool suspension)。在开启池暂停后会有性能会受到一定影响,除非你 真的需要这个功能(例如在冗余的系统下),否则不要开启它。该属性只在使用 Hikari 数 据库连接池时有用。(默认值: false 。)

DataSource

spring.datasource.name 数据源的名称。

spring.datasource.username 数据库的登录用户名。

spring.datasource.password 数据库的登录密码。

spring.datasource.url 数据库的 JDBC URL。

spring.datasource.jdbc-url 用来创建连接的 JDBC URL。

spring.datasource.driver-class-name JDBC 驱动的全限定类名。默认根据 URL 自动检测。

spring.datasource.pool-name 连接池名称。

spring.datasource.max-active 连接池中的最大活跃连接数。

spring.datasource.connection-timeout连接超时(单位毫秒)

spring.datasource.max-age 连接池中连接的最长寿命。

spring.datasource.max-idle 连接池中的最大空闲连接数。

spring.datasource.max-lifetime 连接池中连接的最长寿命(单位为毫秒)。

spring.datasource.max-open-prepared-statements 开启状态的 PreparedStatement 的数量上限。

spring.datasource.max-wait 连接池在等待返回连接时,最长等待多少毫秒再抛出异常。

spring.datasource.maximum-pool-size 连接池能达到的最大规模,包含空闲连接的数量和使用中的连接数量。

spring.datasource.min-evictable-idle-time-millis 一个空闲连接被空闲连接释放器(如果存在的话)优雅地释放前,最短会在连接池里停 留多少时间。

spring.datasource.min-idle 连接池里始终应该保持的最小连接数。(用于 DBCP 和 Tomcat 连接池。)

spring.datasource.minimum-idle: HikariCP 试图在连接池里维持的最小空闲连接数。

spring.datasource.alternate-username-allowed 是否允许其它用户名

spring.datasource.auto-commit 更新操作是否自动提交

spring.datasource.abandon-when-percentage-full 一个百分比形势的阈值,超过该阈值则关闭并报告被弃用的连接

spring.datasource.catalog 默认的 Catalog 名称

spring.datasource.commit-on-return 在连接归还时,连接池是否要提交挂起的事务

spring.datasource.connection-init-sql 在所有新连接创建时都会执行的 SQL 语句,该语句会在连接加入连接池前执行。

spring.datasource.connection-init-sqls 在物理连接第一次创建时执行的 SQL 语句列表。(用于 DBCP 连接池。)

spring.datasource.connection-properties.[key] 设置创建连接时使用的属性。(用于 DBCP 连接池。)

spring.datasource.continue-on-error 初始化数据库时发生错误不要终止。(默认值: false)

spring.datasource.data 指向数据(数据库操纵语言,Data Manipulation Language,DML)脚本资源的引用。

spring.datasource.data-source-class-name 用于获取连接的数据源的全限定类名。

spring.datasource.data-source-jndi 用于获取连接的数据源的 JNDI 位置。

spring.datasource.data-source-properties.[key] 设置创建数据源时使用的属性。(用于 Hikari 连接池。)

spring.datasource.db-properties 设置创建数据源时使用的属性。(用于 Tomcat 连接池。)

spring.datasource.default-auto-commit 连接上的操作是否自动提交。

spring.datasource.default-catalog 连接的默认 Catalog。

spring.datasource.default-read-only 连接的默认只读状态。

spring.datasource.default-transaction-isolation 连接的默认事务隔离级别。

spring.datasource.fair-queue 是否以 FIFO 方式返回连接。

spring.datasource.health-check-properties.[key] 设置要纳入健康检查的属性。(用于 Hikari 连接池。)

spring.datasource.idle-timeout 连接池中的连接能保持闲置状态的最长时间,单位为毫秒。(默认值: 10 。)

spring.datasource.ignore-exception-on-pre-load 初始化数据库连接池时是否要忽略连接。

spring.datasource.init-sql在连接第一次创建时运行的自定义查询。

spring.datasource.initial-size 在连接池启动时要建立的连接数。

spring.datasource.initialization-fail-fast 在连接池创建时,如果达不到最小连接数是否要抛出异常。(默认值: true 。)

spring.datasource.initialize 使用 data.sql 初始化数据库。(默认值: true 。)

spring.datasource.isolate-internal-queries 是否要隔离内部请求。(默认值: false 。)

spring.datasource.jdbc-interceptors 一个分号分隔的类名列表,这些类都扩展了 JdbcInterceptor 类。这些拦截器会插入 java.sql.Connection 对象的操作链里。(用于 Tomcat 连接池。)

spring.datasource.jmx-enabled 开启 JMX 支持(如果底层连接池提供该功能的话)。(默认值: false 。)

spring.datasource.jndi-name 数据源的 JNDI 位置。设置了该属性则忽略类、URL、用户名和密码属性。

spring.datasource.leak-detection-threshold 用来检测 Hikari 连接池连接泄露的阈值,单位为毫秒。

spring.datasource.log-abandoned 是否针对弃用语句或连接的应用程序代码记录下跟踪栈。用于 DBCP 连接池。(默认值: false 。)

spring.datasource.log-validation-errors 在使用 Tomcat 连接池时是否要记录验证错误。

spring.datasource.login-timeout 连接数据库的超时时间(单位为秒)。

spring.datasource.num-tests-per-eviction-run 空闲对象释放器线程(如果存在的话)每次运行时要检查的对象数。

spring.datasource.platform 在 Schema 资源(schema-${platform}.sql)里要使用的平台。(默认值: all 。)

spring.datasource.pool-prepared-statements 是否要将 Statement 放在池里。

spring.datasource.propagate-interrupt-state 对于等待连接的中断线程,是否要传播中断状态。

spring.datasource.read-only 在使用 Hikari 连接池时将数据源设置为只读。

spring.datasource.register-mbeans Hikari 连接池是否要注册 JMX MBean。

spring.datasource.remove-abandoned 被弃用的连接在到达弃用超时后是否应该被移除。

spring.datasource.remove-abandoned-timeout 连接在多少秒后应该考虑弃用。

spring.datasource.rollback-on-return 在连接归还连接池时,是否要回滚挂起的事务。

spring.datasource.schema Schema(数据定义语言,Data Definition Language,DDL)脚本资源的引用。

spring.datasource.separator SQL 初始化脚本里的语句分割符。(默认值: ; 。)

spring.datasource.sql-script-encoding SQL 脚本的编码。

spring.datasource.suspect-timeout 在记录一个疑似弃用连接前要等待多少秒。

spring.datasource.test-on-borrow 从连接池中借用连接时是否要进行测试。

spring.datasource.test-on-connect 在建立连接时是否要进行测试。

spring.datasource.test-on-return 在将连接归还到连接池时是否要进行测试。

spring.datasource.test-while-idle 在连接空闲时是否要进行测试。

spring.datasource.time-between-eviction-runs-millis 在两次空闲连接验证、弃用连接清理和空闲池大小调整之间睡眠的毫秒数。

spring.datasource.transaction-isolation 在使用 Hikari 连接池时设置默认事务隔离级别。

spring.datasource.use-disposable-connection-facade 连接是否要用一个门面(facade)封装起来,在调用了 Connection.close() 后就不能 再使用这个连接了。

spring.datasource.use-equals 在比较方法名时是否使用 String.equals() 来代替 == 。

spring.datasource.use-lock 在操作连接对象时是否要加锁。

spring.datasource.validation-interval 执行连接验证的间隔时间,单位为毫秒。

spring.datasource.validation-query 在连接池里的连接返回给调用者或连接池时,要执行的验证 SQL 查询。

spring.datasource.validation-query-timeout 在连接验证查询执行失败前等待的超时时间,单位为秒。

spring.datasource.validation-timeout 在连接验证失败前等待的超时时间,单位为秒。(用于 Hikari 连接池。)

spring.datasource.validator-class-name 可选验证器类的全限定类名,用于执行测试查询。

spring.datasource.xa.data-source-class-name XA 数据源的全限定类名。

spring.datasource.xa.properties 要传递给 XA 数据源的属性。

FreeMarker

spring.freemarker.allow-request-override HttpServletRequest 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.freemarker.allow-session-override HttpSession 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.freemarker.cache 开启模板缓存。

spring.freemarker.charset 模板编码。

spring.freemarker.check-template-location 检查模板位置是否存在。

spring.freemarker.content-type Content-Type 的值。

spring.freemarker.enabled 开启 FreeMarker 的 MVC 视图解析。

spring.freemarker.expose-request-attributes 在模型合并到模板前,是否要把所有的请求属性添加到模型里。

spring.freemarker.expose-session-attributes 在模型合并到模板前,是否要把所有的 HttpSession 属性添加到模型里。

spring.freemarker.expose-spring-macro-helpers 是否发布供 Spring 宏程序库使用的 RequestContext ,并将命其名为 springMacro- RequestContext

spring.freemarker.prefer-file-system-access 加载模板时优先通过文件系统访问。文件系统访问能够实时检测到模板变更。(默认值: true 。)

spring.freemarker.prefix 在构建 URL 时添加到视图名称前的前缀。

spring.freemarker.request-context-attribute 在所有视图里使用的 RequestContext 属性的名称。

spring.freemarker.settings 要传递给 FreeMarker 配置的各种键。

spring.freemarker.suffix 在构建 URL 时添加到视图名称后的后缀。

spring.freemarker.template-loader-path 模板路径列表,用逗号分隔。(默认值: [“classpath:/templates/”] 。)

spring.freemarker.view-names 可解析的视图名称的白名单。

Groovy

spring.groovy.template.allow-request-override HttpServletRequest 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.groovy.template.allow-session-override HttpSession 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.groovy.template.cache 开启模板缓存。

spring.groovy.template.charset 模板编码。

spring.groovy.template.check-template-location 检查模板位置是否存在。

spring.groovy.template.configuration.auto-escape 模型变量在模板里呈现时是否要做转义。(默认值: false 。)

spring.groovy.template.configuration.auto-indent 模板是否要自动呈现缩进。(默认值: false 。)

spring.groovy.template.configuration.auto-indent-string 开启自动缩进时用于缩进的字符串,可以是 SPACES ,也可以是 TAB 。(默认值: SPACES 。)

spring.groovy.template.configuration.auto-new-line 模板里是否要呈现新的空行。(默认值: false 。)

spring.groovy.template.configuration.base-template-class 模板基类。

spring.groovy.template.configuration.cache-templates 模板是否应该缓存。(默认值: true 。)

spring.groovy.template.configuration.declaration-encoding 用来写声明头的编码。

spring.groovy.template.configuration.expand-empty-elements 没有正文的元素该用短形式(例如, )还是扩展形式(例如, )来书 写。(默认值: false)

spring.groovy.template.configuration.locale 设置模板地域。

spring.groovy.template.configuration.new-line-string 在自动空行开启后用来呈现空行的字符串。(默认为系统的 line.separator 属性值。)

spring.groovy.template.configuration.resource-loader-path Groovy 模板的路径。(默认值: classpath:/templates/ 。)

spring.groovy.template.configuration.use-double-quotes 属性是该用双引号还是单引号。(默认值: false 。)

spring.groovy.template.content-type Content-Type 的值。

spring.groovy.template.enabled 开启 Groovy 模板的 MVC 视图解析。

spring.groovy.template.expose-request-attributes 在模型合并到模板前,是否要把所有的请求属性添加到模型里。

spring.groovy.template.expose-session-attributes 在模型合并到模板前,是否要把所有的 HttpSession 属性添加到模型里。

spring.groovy.template.expose-spring-macro-helpers 是否发布供 Spring 宏程序库使用的 RequestContext ,并将其命名为 springMacro- RequestContext

spring.groovy.template.prefix 在构建 URL 时,添加到视图名称前的前缀。

spring.groovy.template.request-context-attribute 所有视图里使用的 RequestContext 属性的名称。

spring.groovy.template.resource-loader-path 模板路径(默认值: classpath:/ templates/ 。)

spring.groovy.template.suffix 在构建 URL 时,添加到视图名称后的后缀。

spring.groovy.template.view-names 可解析的视图名称白名单。

H2

spring.h2.console.enabled 开启控制台。(默认值: false 。)

spring.h2.console.path 可以找到控制台的路径。(默认值: /h2-console 。)

Hornetq

spring.hornetq.embedded.cluster-password 集群密码。默认在启动时随机生成。

spring.hornetq.embedded.data-directory 日志文件目录。如果关闭了持久化功能则不需要该属性。

spring.hornetq.embedded.enabled 如果有 HornetQ 服务器 API,则开启嵌入模式。(默认值: true 。)

spring.hornetq.embedded.persistent 开启持久化存储。(默认值: false 。)

spring.hornetq.embedded.queues 启动时要创建的队列列表,用逗号分隔。(默认值: [] 。)

spring.hornetq.embedded.server-id 服务器 ID。默认使用自增长计数器。(默认值: 0 。)

spring.hornetq.embedded.topics 启动时要创建的主题列表,用逗号分隔。(默认值: [] 。)

spring.hornetq.host HornetQ 的主机。(默认值: localhost 。)

spring.hornetq.mode HornetQ 的部署模式,默认为自动检测。可以显式地设置为 native 或 embedded 。

spring.hornetq.port HornetQ 的端口。(默认值: 5445 。)

Http

spring.http.converters.preferred-json-mapper HTTP 消息转换时优先使用 JSON 映射器。

spring.http.encoding.charset HTTP 请求和响应的字符集。如果没有显式地指定 Content-Type 头,则将该属性值作为 这个头的值。(默认值: UTF-8 。)

spring.http.encoding.enabled 开启 HTTP 编码支持。(默认值: true 。)

spring.http.encoding.force 强制将 HTTP 请求和响应编码为所配置的字符集。(默认值: true 。)

Jackson

spring.jackson.date-format 日期格式字符串(yyyy-MM-dd HH:mm:ss)或日期格式类的全限定类名。

spring.jackson.deserialization 影响 Java 对象反序列化的 Jackson on/off 特性。

spring.jackson.generator 用于生成器的 Jackson on/off 特性。

spring.jackson.joda-date-time-format Joda 日期时间格式字符串(yyyy-MM-dd HH:mm:ss)。如果没有配置,而 date-format 又配置了一个格式字符串的话,会将它作为降级配置。

spring.jackson.locale 用于格式化的地域值。

spring.jackson.mapper Jackson 的通用 on/off 特性。

spring.jackson.parser 用于解析器的 Jackson on/off 特性。

spring.jackson.property-naming-strategy Jackson 的 PropertyNamingStrategy 中的一个常量( CAMEL_CASE_TO_LOWERCASE WITH_UNDERSCORES )。也可以设置 PropertyNamingStrategy 的子类的全限定类名。

spring.jackson.serialization 影响 Java 对象序列化的 Jackson on/off 特性。

spring.jackson.serialization-inclusion 控制序列化时要包含哪些属性。可选择 Jackson 的 JsonInclude.Include 枚举里的某个值。

spring.jackson.time-zone 格式化日期时使用的时区。可以配置各种可识别的时区标识符,比如 America/Los_ Angeles 或者 GMT+10 。

Jersey

spring.jersey.filter.order Jersey 过滤器链的顺序。(默认值: 0 。)

spring.jersey.init 通过 Servlet 或过滤器传递给 Jersey 的初始化参数。

spring.jersey.type Jersey 集成类型。可以是 servlet 或者 filter 。

Jms

spring.jms.jndi-name 连接工厂的 JNDI 名字。设置了该属性,则优先于其他自动配置的连接工厂。

spring.jms.listener.acknowledge-mode 容器的应答模式(acknowledgment mode)。默认情况下,监听器使用自动应答。

spring.jms.listener.auto-startup 启动时自动启动容器。(默认值: true 。)

spring.jms.listener.concurrency 并发消费者的数量下限。

spring.jms.listener.max-concurrency 并发消费者的数量上限。

spring.jms.pub-sub-domain 如果是主题而非队列,指明默认的目的地类型是否支持 Pub/Sub。(默认值: false 。)

Jmx

spring.jmx.default-domain JMX 域名。

spring.jmx.enabled 将管理 Bean 发布到 JMX 域里。(默认值: true 。)

spring.jmx.server MBeanServer 的 Bean 名称。(默认值: mbeanServer 。)

Jpa

spring.jpa.database 要操作的目标数据库,默认自动检测。也可以通过 databasePlatform 属性进行设置。

spring.jpa.database-platform 要操作的目标数据库,默认自动检测。也可以通过 Database 枚举来设置。

spring.jpa.generate-ddl 启动时要初始化 Schema。(默认值: false 。)

spring.jpa.hibernate.ddl-auto DDL 模式( none 、 validate 、 update 、 create 和 create-drop )。这是 hibernate. hbm2ddl.auto 属性的一个快捷方式。在使用嵌入式数据库时,默认为 create-drop , 其他情况下默认为 none 。

spring.jpa.hibernate.naming-strategy Hibernate 命名策略的全限定类名。

spring.jpa.open-in-view 注册 OpenEntityManagerInViewInterceptor ,在请求的整个处理过程中,将一个 JPA EntityManager 绑定到线程上。(默认值: true)

spring.jpa.propertiesJPA 提供方要设置的额外原生属性。

spring.jpa.show-sql 在使用 Bitronix Transaction Manager 时打开 SQL 语句日志。(默认值: false 。)

Jta

spring.jta.allow-multiple-lrc 在使用 Bitronix Transaction Manager 时,事务管理器是否应该允许一个事务涉及多个 LRC 资源。(默认值: false)

spring.jta.asynchronous2-pc 在使用 Bitronix Transaction Manager 时,是否异步执行两阶段提交。(默认值: false 。)

spring.jta.background-recovery-interval在使用 Bitronix Transaction Manager 时,多久运行一次恢复过程,单位为分钟。(默认值: 1 )

spring.jta.background-recovery-interval-seconds 在使用 Bitronix Transaction Manager 时,多久运行一次恢复过程,单位为秒。(默认值: 60 )

spring.jta.current-node-only-recovery 在使用 Bitronix Transaction Manager 时,恢复是否要滤除不包含本 JVM 唯一 ID 的 XID。(默认值: true )

spring.jta.debug-zero-resource-transaction 在使用 Bitronix Transaction Manager 时,对于没有涉及任何资源的事务,是否要跟踪并记 录它们的创建和提交调用栈。(默认值: false)

spring.jta.default-transaction-timeout 在使用 Bitronix Transaction Manager 时,默认的事务超时时间,单位为秒。(默认值: 60 。)

spring.jta.disable-jmx 在使用 Bitronix Transaction Manager 时,是否要禁止注册 JMX MBean。(默认值: false 。)

spring.jta.enabled 开启 JTA 支持。(默认值: true 。)

spring.jta.exception-analyzer 在使用 Bitronix Transaction Manager 时用到的异常分析器。设置为 null 时使用默认异常分析器,也可以设置自定义异常分析器的全限定类名。

spring.jta.filter-log-status 在使用 Bitronix Transaction Manager 时,是否只记录必要的日志。开启该参数时能减少分 段(fragment)空间用量,但调试更复杂了。(默认值: false)

spring.jta.force-batching-enabled 在使用 Bitronix Transaction Manager 时,是否批量输出至磁盘。禁用批处理会严重降低事 务管理器的吞吐量。(默认值: true 。)

spring.jta.forced-write-enabled 在使用 Bitronix Transaction Manager 时,日志是否强制写到磁盘上。在生产环境里不要设 置为 false ,因为不强制写到磁盘上无法保证完整性。(默认值: true)

spring.jta.graceful-shutdown-interval 在使用 Bitronix Transaction Manager 时,要关闭的话,事务管理器在放弃事务前最多等它 多少秒。(默认值: 60)

spring.jta.jndi-transaction-synchronization-registry-name 在使用 Bitronix Transaction Manager 时,事务同步注册表应该绑定到哪个 JNDI 下。(默认 值: java:comp/TransactionSynchronizationRegistry)

spring.jta.jndi-user-transaction-name 在使用 Bitronix Transaction Manager 时,用户事务应该绑定到哪个 JNDI 下。(默认值: java:comp/UserTransaction 。)

spring.jta.journal 在使用 Bitronix Transaction Manager 时,要用的日志名。可以是 disk 、 null 或者全限定类 名。(默认值: disk 。)

spring.jta.log-dir 事务日志目录。

spring.jta.log-part1-filename 日志分段文件 1 的名称。(默认值: btm1.tlog 。)

spring.jta.log-part2-filename 日志分段文件 2 的名称。(默认值: btm2.tlog 。)

spring.jta.max-log-size-in-mb 在使用 Bitronix Transaction Manager 时,日志分段文件的最大兆数。日志越大,事务就被 允许在未终结状态停留越长时间。但是,如果文件大小限制得太小,事务管理器在分段 满了的时候就会暂停更长时间。(默认值: 2 。)

spring.jta.resource-configuration-filename Bitronix Transaction Manager 的配置文件名。

spring.jta.server-id 唯一标识 Bitronix Transaction Manager 实例的 ID。

spring.jta.skip-corrupted-logs 是否跳过损坏的日志文件。(默认值: false 。)

spring.jta.transaction-manager-id 事务管理器的唯一标识符。

spring.jta.warn-about-zero-resource-transaction 在使用 Bitronix Transaction Manager 时,是否要对执行时没有涉及任何资源的事务作出告 警。(默认值: true 。)

Mail

spring.mail.default-encoding 默认的 MimeMessage 编码。(默认值: UTF-8 。)

spring.mail.host SMTP 服务器主机地址。

spring.mail.jndi-name会话的 JNDI 名称。设置之后,该属性的优先级要高于其他邮件设置。

spring.mail.password SMTP 服务器的登录密码。

spring.mail.port SMTP 服务器的端口号。

spring.mail.properties 附加的 JavaMail 会话属性。

spring.mail.protocol SMTP 服务器用到的协议。(默认值: smtp 。)

spring.mail.test-connection 在启动时测试邮件服务器是否可用。(默认值: false 。)

spring.mail.username SMTP 服务器的登录用户名。

Messages

spring.messages.basename 逗号分隔的基本名称列表,都遵循 ResourceBundle 的惯例。本质上这就是一个全限定 的 Classpath 位置,如果不包含包限定符(比如 org.mypackage ),就会从 Classpath 的根部开始解析。(默认值: messages 。)

spring.messages.cache-seconds 加载的资源包文件的缓存失效时间,单位为秒。在设置为 -1 时,包会永远缓存。(默认值: -1 。)

spring.messages.encoding消息包的编码。(默认值: UTF-8 。)

Mobile

spring.mobile.devicedelegatingviewresolver.enable-fallback 开启降级解析支持。(默认值: false 。)

spring.mobile.devicedelegatingviewresolver.enabled 开启设备视图解析器。(默认值: false 。)

spring.mobile.devicedelegatingviewresolver.mobile-prefix 添加到移动设备视图名前的前缀。(默认值: mobile/ 。)

spring.mobile.devicedelegatingviewresolver.mobile-suffix 添加到移动设备视图名后的后缀。

spring.mobile.devicedelegatingviewresolver.normal-prefix 添加到普通设备视图名前的前缀。

spring.mobile.devicedelegatingviewresolver.normal-suffix 添加到普通设备视图名后的后缀。

spring.mobile.devicedelegatingviewresolver.tablet-prefix添加到平板设备视图名前的前缀。(默认值: tablet/ 。)

spring.mobile.devicedelegatingviewresolver.tablet-suffix 添加到平板设备视图名后的后缀。

spring.mobile.sitepreference.enabled 开启 SitePreferenceHandler 。(默认值: true 。)

Mongodb

spring.mongodb.embedded.features要开启的特性列表,用逗号分隔。

spring.mongodb.embedded.version 要使用的 Mongo 版本。(默认值: 2.6.10 。)

Mustache

spring.mustache.cache 开启模板缓存。

spring.mustache.charset 模板编码。

spring.mustache.check-template-location 检查模板位置是否存在。

spring.mustache.content-type Content-Type 的值。

spring.mustache.enabled 开启 Mustache 的 MVC 视图解析。

spring.mustache.prefix添加到模板名前的前缀。(默认值: classpath:/ templates/ 。)

spring.mustache.suffix 添加到模板名后的后缀。(默认值: .html 。)

spring.mustache.view-names 可解析的视图名称的白名单。

Mvc

spring.mvc.async.request-timeout 异步请求处理超时前的等待时间(单位为毫秒)。如果没有设置该属性,则使用底层实现 的默认超时时间,比如,Tomcat 上使用 Servlet 3 时超时时间为 10 秒。

spring.mvc.date-format 要使用的日期格式(比如 dd/MM/yyyy )。

spring.mvc.favicon.enabled 开启 favicon.ico 的解析。(默认值: true 。)

spring.mvc.ignore-default-model-on-redirect 在重定向的场景下,是否要忽略“默认”模型对象的内容。(默认值: true 。)

spring.mvc.locale 要使用的地域配置。

spring.mvc.message-codes-resolver-format 消息代码格式( PREFIX_ERROR_CODE 、 POSTFIX_ERROR_CODE )。

spring.mvc.view.prefix Spring MVC 视图前缀。

spring.mvc.view.suffix Spring MVC 视图后缀。

Mybatis

mybatis.mapper-locations mybatis 映射文件位置。
mybatis.type-aliases-package 别名包位置。

Rabbitmq

spring.rabbitmq.addresses 客户端应该连接的地址列表,用逗号分隔。

spring.rabbitmq.dynamic 创建一个 AmqpAdmin Bean。(默认值: true 。)

spring.rabbitmq.host RabbitMQ 主机地址。(默认值: localhost 。)

spring.rabbitmq.listener.acknowledge-mode 容器的应答模式。

spring.rabbitmq.listener.auto-startup 启动时自动开启容器。(默认值: true 。)

spring.rabbitmq.listener.concurrency 消费者的数量下限。

spring.rabbitmq.listener.max-concurrency 消费者的数量上限。

spring.rabbitmq.listener.prefetch 单个请求里要处理的消息数。该数值不应小于事务数(如果用到的话)。

spring.rabbitmq.listener.transaction-size 一个事务里要处理的消息数。为了保证效果,应该不大于预先获取的数量。

spring.rabbitmq.password进行身份验证的密码。

spring.rabbitmq.port RabbitMQ 端口。(默认值: 5672 。)

spring.rabbitmq.requested-heartbeat 请求心跳超时,单位为秒; 0 表示不启用心跳。

spring.rabbitmq.ssl.enabled 开启 SSL 支持。(默认值: false 。)

spring.rabbitmq.ssl.key-store 持有 SSL 证书的 KeyStore 路径。

spring.rabbitmq.ssl.key-store-password 访问 KeyStore 的密码。

spring.rabbitmq.ssl.trust-store 持有 SSL 证书的 TrustStore。

spring.rabbitmq.ssl.trust-store-password 访问 TrustStore 的密码。

spring.rabbitmq.username 进行身份验证的用户名。

spring.rabbitmq.virtual-host 在连接 RabbitMQ 时的虚拟主机。

Redis

spring.redis.database 连接工厂使用的数据库索引。(默认值: 0 。)

spring.redis.host Redis 服务器主机地址。(默认值: localhost 。)

spring.redis.passwordRedis 服务器的登录密码。

spring.redis.pool.max-active连接池在指定时间里能分配的最大连接数。负数表示无限制。(默认值: 8 。)

spring.redis.pool.max-idle 连接池里的最大空闲连接数。负数表示空闲连接数可以是无限大。(默认值: 8 。)

spring.redis.pool.max-wait当连接池被耗尽时,分配连接的请求应该在抛出异常前被阻塞多长时间(单位为秒)。负 数表示一直阻塞。(默认值: -1 。)

spring.redis.pool.min-idle 连接池里要维持的最小空闲连接数。该属性只有在设置为正数时才有效。(默认值: 0 。)

spring.redis.port Redis 服务器端口。(默认值: 6379 。)

spring.redis.sentinel.master Redis 服务器的名字。

spring.redis.sentinel.nodes形如“主机: 端口”配对的列表,用逗号分隔。

spring.redis.timeout 连接超时时间,单位为秒。(默认值: 0 。)

Resources

spring.resources.add-mappings 开启默认资源处理。(默认值: true 。)

spring.resources.cache-period 资源处理器对资源的缓存周期,单位为秒。

spring.resources.chain.cache 对资源链开启缓存。(默认值: true 。)

spring.resources.chain.enabled 开启 Spring 资源处理链。(默认关闭的,除非至少开启了一个策略。)

spring.resources.chain.html-application-cache 开启 HTML5 应用程序缓存证明重写。(默认值: false 。)

spring.resources.chain.strategy.content.enabled 开启内容版本策略。(默认值: false 。)

spring.resources.chain.strategy.content.paths 要运用于版本策略的模式列表,用逗号分隔。(默认值: [/**] 。)

spring.resources.chain.strategy.fixed.enabled开启固定版本策略。(默认值: false 。)

spring.resources.chain.strategy.fixed.paths要运用于固定版本策略的模式列表,用逗号分隔。

spring.resources.chain.strategy.fixed.version 用于固定版本策略的版本字符串。

spring.resources.static-locations 静态资源位置。默认为 classpath: [/META-INF/resources/, /resources/, /static/, /public/] 加上 context:/(Servlet 上下文的根目录)。

SendGrid

spring.sendgrid.password SendGrid 密码。

spring.sendgrid.proxy.host SendGrid 代理主机地址。

spring.sendgrid.proxy.port SendGrid 代理端口。

spring.sendgrid.username SendGrid 用户名。

Social

spring.social.auto-connection-views 针对所支持的提供方开启连接状态视图。(默认值: false 。)

spring.social.facebook.app-id 应用程序 ID。

spring.social.facebook.app-secret 应用程序的密钥。

spring.social.linkedin.app-id 应用程序 ID。

spring.social.linkedin.app-secret 应用程序的密钥。

spring.social.twitter.app-id 应用程序 ID。

spring.social.twitter.app-secret 应用程序的密钥。

Thymeleaf

spring.thymeleaf.cache开启模板缓存。(默认值: true 。)

spring.thymeleaf.check-template-location 检查模板位置是否存在。(默认值: true 。)

spring.thymeleaf.content-type Content-Type 的值。(默认值: text/html 。)

spring.thymeleaf.enabled 开启 MVC Thymeleaf 视图解析。(默认值: true 。)

spring.thymeleaf.encoding模板编码。(默认值: UTF-8 。)

spring.thymeleaf.excluded-view-names 要被排除在解析之外的视图名称列表,用逗号分隔。

spring.thymeleaf.mode 要运用于模板之上的模板模式。另见 StandardTemplate- ModeHandlers 。(默认值: HTML5 。)

spring.thymeleaf.prefix 在构建 URL 时添加到视图名称前的前缀。(默认值: classpath:/templates/ 。)

spring.thymeleaf.suffix 在构建 URL 时添加到视图名称后的后缀。(默认值: .html 。)

spring.thymeleaf.template-resolver-order Thymeleaf 模板解析器在解析器链中的顺序。默认情况下,它排在第一位。顺序从 1 开始只有在定义了额外的 TemplateResolver Bean 时才需要设置这个属性。

spring.thymeleaf.view-names 可解析的视图名称列表,用逗号分隔。

Velocity

spring.velocity.allow-request-override HttpServletRequest 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.velocity.allow-session-override HttpSession` 的属性是否允许覆盖(隐藏)控制器生成的同名模型属性。

spring.velocity.cache 开启模板缓存。

spring.velocity.charset 模板编码。

spring.velocity.check-template-location 检查模板位置是否存在。

spring.velocity.content-type Content-Type 的值。

spring.velocity.date-tool-attribute DateTool 辅助对象在视图的 Velocity 上下文里呈现的名字。

spring.velocity.enabled 开启 Velocity 的 MVC 视图解析。

spring.velocity.expose-request-attributes 在模型合并到模板前,是否要把所有的请求属性添加到模型里。

spring.velocity.expose-session-attributes 在模型合并到模板前,是否要把所有的 HttpSession 属性添加到模型里。

spring.velocity.expose-spring-macro-helpers 是否发布供 Spring 宏程序库使用的 RequestContext ,并将其名命为 springMacro- RequestContext 。

spring.velocity.number-tool-attribute NumberTool 辅助对象在视图的 Velocity 上下文里呈现的名字。

spring.velocity.prefer-file-system-access 加载模板时优先通过文件系统访问。文件系统访问能够实时检测到模板变更。(默认值: true 。)

spring.velocity.prefix在构建 URL 时添加到视图名称前的前缀。

spring.velocity.properties 额外的 Velocity 属性。

spring.velocity.request-context-attribute所有视图里使用的 Request- Context 属性的名称。

spring.velocity.resource-loader-path 模板路径。(默认值: classpath:/ templates/ 。)

spring.velocity.suffix 在构建 URL 时添加到视图名称后的后缀。

spring.velocity.toolbox-config-location Velocity Toolbox 的配置位置,比如 /WEB-INF/toolbox.xml。自动加载 Velocity Tools 工具定 义文件,将所定义的全部工具发布到指定的作用域内。

spring.velocity.view-names可解析的视图名称白名单。

View

spring.view.prefix Spring MVC 视图前缀。

spring.view.suffixSpring MVC 视图后缀。

其它

spring.aop.auto 添加 @EnableAspectJAutoProxy(默认:true)

spring.application.admin.enabled开启应用程序的管理功能 (默认:false)

spring.artemis.embedded.cluster-password 集群密码。默认在启东市随机生成

spring.artemis.embedded.persistent开启持久化存储 (默认:false)

spring.autoconfigure.exclude 要排除的自动配置类

转载请注明:刘召考的博客 » Spring Boot application.properties 配置参数详情

]]>
http://www.liuzk.com/464.html/feed 0
intellij debug时提示”Method breakpoints may dramatically slow down debugging“的解决办法 http://www.liuzk.com/448.html http://www.liuzk.com/448.html#comments Tue, 24 Dec 2019 08:29:36 +0000 http://www.liuzk.com/?p=448 最近在debug的时候,遇到的IDEA特别慢的情况,一直卡着。仔细看,原来在刚运行debug的时候提示:

20191224162144

 

解决办法:

1,View Breakpoints

20191224162532

 

2,把 “Java Method Breakpoints” 取消,”Done“

20191224162836

 

这样,再次启动 debug,完美解决。

 

 

 

转载请注明:刘召考的博客 » intellij debug时提示”Method breakpoints may dramatically slow down debugging“的解决办法

]]>
http://www.liuzk.com/448.html/feed 1
[Command line is too long. Shorten command line for…]解决方案 http://www.liuzk.com/441.html http://www.liuzk.com/441.html#comments Fri, 06 Dec 2019 09:55:04 +0000 http://www.liuzk.com/?p=441 IDEA run工程的时候,抛出异常:

Error running ‘QCGradeTest': Command line is too long. Shorten command line for QCGradeTest or also for Application default configuration

解决方案:

在项目里 .idea\workspace.xml,
找到标签 <component name=”PropertiesComponent”> ,
在标签里加一行 <property name=”dynamic.classpath” value=”true” />

20191206175206

转载请注明:刘召考的博客 » [Command line is too long. Shorten command line for…]解决方案

]]>
http://www.liuzk.com/441.html/feed 0
MySQL索引-B+树(看完你就明白了) http://www.liuzk.com/410.html http://www.liuzk.com/410.html#comments Tue, 12 Nov 2019 11:33:40 +0000 http://www.liuzk.com/?p=410 索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据。
索引最形象的比喻就是图书的目录了。注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 这个数据,直接对全数据检索也很快,没有必要费力气建索引再去查找。

索引在 MySQL 数据库中分三类:

  • B+ 树索引
  • Hash 索引
  • 全文索引

我们今天要介绍的是工作开发中最常接触到的 InnoDB 存储引擎中的 B+ 树索引。要介绍 B+ 树索引,就不得不提二叉查找树,平衡二叉树和 B 树这三种数据结构。B+ 树就是从他们仨演化来的。

二叉查找树

首先,让我们先看一张图:

1

 

从图中可以看到,我们为 user 表(用户信息表)建立了一个二叉查找树的索引。

图中的圆为二叉查找树的节点,节点中存储了键(key)和数据(data)。键对应 user 表中的 id,数据对应 user 表中的行数据。

二叉查找树的特点就是任何节点的左子节点的键值都小于当前节点的键值,右子节点的键值都大于当前节点的键值。顶端的节点我们称为根节点,没有子节点的节点我们称之为叶节点。

如果我们需要查找 id=12 的用户信息,利用我们创建的二叉查找树索引,查找流程如下:

  • 将根节点作为当前节点,把 12 与当前节点的键值 10 比较,12 大于 10,接下来我们把当前节点>的右子节点作为当前节点。
  • 继续把 12 和当前节点的键值 13 比较,发现 12 小于 13,把当前节点的左子节点作为当前节点。
  • 把 12 和当前节点的键值 12 对比,12 等于 12,满足条件,我们从当前节点中取出 data,即 id=12,name=xm。

 

利用二叉查找树我们只需要 3 次即可找到匹配的数据。如果在表中一条条的查找的话,我们需要 6 次才能找到。

平衡二叉树

上面我们讲解了利用二叉查找树可以快速的找到数据。但是,如果上面的二叉查找树是这样的构造:

2

 

 

这个时候可以看到我们的二叉查找树变成了一个链表。如果我们需要查找 id=17 的用户信息,我们需要查找 7 次,也就相当于全表扫描了。 
导致这个现象的原因其实是二叉查找树变得不平衡了,也就是高度太高了,从而导致查找效率的不稳定。
为了解决这个问题,我们需要保证二叉查找树一直保持平衡,就需要用到平衡二叉树了。 
平衡二叉树又称 AVL 树,在满足二叉查找树特性的基础上,要求每个节点的左右子树的高度差不能超过 1。 
下面是平衡二叉树和非平衡二叉树的对比:
3

 

由平衡二叉树的构造我们可以发现第一张图中的二叉树其实就是一棵平衡二叉树。

平衡二叉树保证了树的构造是平衡的,当我们插入或删除数据导致不满足平衡二叉树不平衡时,平衡二叉树会进行调整树上的节点来保持平衡。具体的调整方式这里就不介绍了。
平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。

B 树

因为内存的易失性。一般情况下,我们都会选择将 user 表中的数据和索引存储在磁盘这种外围设备中。
但是和内存相比,从磁盘中读取数据的速度会慢上百倍千倍甚至万倍,所以,我们应当尽量减少从磁盘中读取数据的次数。
另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。
如果我们能把尽量多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。
如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。
我们都知道平衡二叉树可是每个节点只存储一个键值和数据的。那说明什么?说明每个磁盘块仅仅存储一个键值和数据!那如果我们要存储海量的数据呢?

可以想象到二叉树的节点将会非常多,高度也会极其高,我们查找数据时也会进行很多次磁盘 IO,我们查找数据的效率将会极低!

4

为了解决平衡二叉树的这个弊端,我们应该寻找一种单个节点可以存储多个键值和数据的平衡树。也就是我们接下来要说的 B 树。

B 树(Balance Tree)即为平衡树的意思,下图即是一棵 B 树:

5

图中的 p 节点为指向子节点的指针,二叉查找树和平衡二叉树其实也有,因为图的美观性,被省略了。

图中的每个节点称为页,页就是我们上面说的磁盘块,在 MySQL 中数据读取的基本单位都是页,所以我们这里叫做页更符合 MySQL 中索引的底层数据结构。

 

从上图可以看出,B 树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,上述图中的 B 树为 3 阶 B 树,高度也会很低。

基于这个特性,B 树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。

假如我们要查找 id=28 的用户信息,那么我们在上图 B 树中查找的流程如下:

  • 先找到根节点也就是页 1,判断 28 在键值 17 和 35 之间,那么我们根据页 1 中的指针 p2 找到页 3。
  • 将 28 和页 3 中的键值相比较,28 在 26 和 30 之间,我们根据页 3 中的指针 p2 找到页 8。
  • 将 28 和页 8 中的键值相比较,发现有匹配的键值 28,键值 28 对应的用户信息为(28,bv)。

 

B+ 树

B+ 树是对 B 树的进一步优化。让我们先来看下 B+ 树的结构图:

6

 

根据上图我们来看下 B+ 树和 B 树有什么不同:

①B+ 树非叶子节点上是不存储数据的,仅存储键值,而 B 树节点中不仅存储键值,也会存储数据。

之所以这么做是因为在数据库中页的大小是固定的,InnoDB 中页的默认大小是 16KB。

如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的 IO 次数又会再次减少,数据查询的效率也会更快。

另外,B+ 树的阶数是等于键值的数量的,如果我们的 B+ 树一个节点可以存储 1000 个键值,那么 3 层 B+ 树可以存储 1000×1000×1000=10 亿个数据。

一般根节点是常驻内存的,所以一般我们查找 10 亿数据,只需要 2 次磁盘 IO。

②因为 B+ 树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的。

那么 B+ 树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。而 B 树因为数据分散在各个节点,要实现这一点是很不容易的。

有心的读者可能还发现上图 B+ 树中各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的。

其实上面的 B 树我们也可以对各个节点加上链表。这些不是它们之前的区别,是因为在 MySQL 的 InnoDB 存储引擎中,索引就是这样存储的。

也就是说上图中的 B+ 树索引就是 InnoDB 中 B+ 树索引真正的实现方式,准确的说应该是聚集索引(聚集索引和非聚集索引下面会讲到)。

通过上图可以看到,在 InnoDB 中,我们通过数据页之间通过双向链表连接以及叶子节点中数据之间通过单向链表连接的方式可以找到表中所有的数据。

MyISAM 中的 B+ 树索引实现与 InnoDB 中的略有不同。在 MyISAM 中,B+ 树索引的叶子节点并不存储数据,而是存储数据的文件地址。

 

聚集索引 VS 非聚集索引

在上节介绍 B+ 树索引的时候,我们提到了图中的索引其实是聚集索引的实现方式。

那什么是聚集索引呢?在 MySQL 中,B+ 树索引按照存储方式的不同分为聚集索引和非聚集索引。

这里我们着重介绍 InnoDB 中的聚集索引和非聚集索引:

聚集索引(聚簇索引):以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。

这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。

这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。

非聚集索引(非聚簇索引):以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。

非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。

明白了聚集索引和非聚集索引的定义,我们应该明白这样一句话:数据即索引,索引即数据。

利用聚集索引和非聚集索引查找数据

前面我们讲解 B+ 树索引的时候并没有去说怎么在 B+ 树中进行数据的查找,主要就是因为还没有引出聚集索引和非聚集索引的概念。

下面我们通过讲解如何通过聚集索引以及非聚集索引查找数据表中数据的方式介绍一下 B+ 树索引查找数据方法。

利用聚集索引查找数据

7

还是这张 B+ 树索引图,现在我们应该知道这就是聚集索引,表中的数据存储在其中。

现在假设我们要查找 id>=18 并且 id<40 的用户数据。对应的 sql 语句为:

select * from user where id>=18 and id <40

其中 id 为主键,具体的查找过程如下:

①一般根节点都是常驻内存的,也就是说页 1 已经在内存中了,此时不需要到磁盘中读取数据,直接从内存中读取即可。

从内存中读取到页 1,要查找这个 id>=18 and id <40 或者范围值,我们首先需要找到 id=18 的键值。

从页 1 中我们可以找到键值 18,此时我们需要根据指针 p2,定位到页 3。

②要从页 3 中查找数据,我们就需要拿着 p2 指针去磁盘中进行读取页 3。

从磁盘中读取页 3 后将页 3 放入内存中,然后进行查找,我们可以找到键值 18,然后再拿到页 3 中的指针 p1,定位到页 8。

③同样的页 8 页不在内存中,我们需要再去磁盘中将页 8 读取到内存中。

将页 8 读取到内存中后。因为页中的数据是链表进行连接的,而且键值是按照顺序存放的,此时可以根据二分查找法定位到键值 18。

此时因为已经到数据页了,此时我们已经找到一条满足条件的数据了,就是键值 18 对应的数据。

因为是范围查找,而且此时所有的数据又都存在叶子节点,并且是有序排列的,那么我们就可以对页 8 中的键值依次进行遍历查找并匹配满足条件的数据。

我们可以一直找到键值为 22 的数据,然后页 8 中就没有数据了,此时我们需要拿着页 8 中的 p 指针去读取页 9 中的数据。

④因为页 9 不在内存中,就又会加载页 9 到内存中,并通过和页 8 中一样的方式进行数据的查找,直到将页 12 加载到内存中,发现 41 大于 40,此时不满足条件。那么查找到此终止。

最终我们找到满足条件的所有数据,总共 12 条记录:

(18,kl), (19,kl), (22,hj), (24,io), (25,vg) , (29,jk), (31,jk) , (33,rt) , (34,ty) , (35,yu) , (37,rt) , (39,rt) 。

下面看下具体的查找流程图

8

利用非聚集索引查找数据

 

9

读者看到这张图的时候可能会蒙,这是啥东西啊?怎么都是数字。如果有这种感觉,请仔细看下图中红字的解释。

什么?还看不懂?那我再来解释下吧。首先,这个非聚集索引表示的是用户幸运数字的索引(为什么是幸运数字?一时兴起想起来的:-)),此时表结构是这样的。

91

在叶子节点中,不再存储所有的数据了,存储的是键值和主键。对于叶子节点中的 x-y,比如 1-1。左边的 1 表示的是索引的键值,右边的 1 表示的是主键值。

如果我们要找到幸运数字为 33 的用户信息,对应的 sql 语句为:

select * from user where luckNum=33

查找的流程跟聚集索引一样,这里就不详细介绍了。我们最终会找到主键值 47,找到主键后我们需要再到聚集索引中查找具体对应的数据信息,此时又回到了聚集索引的查找流程。

下面看下具体的查找流程图:

92

在 MyISAM 中,聚集索引和非聚集索引的叶子节点都会存储数据的文件地址。

总结

本篇文章从二叉查找树,详细说明了为什么 MySQL 用 B+ 树作为数据的索引,以及在 InnoDB 中数据库如何通过 B+ 树索引来存储数据以及查找数据。
我们一定要记住这句话:数据即索引,索引即数据。

转载请注明:刘召考的博客 » MySQL索引-B+树(看完你就明白了)

]]>
http://www.liuzk.com/410.html/feed 0
Office 2019激活办法–亲试有效 http://www.liuzk.com/405.html http://www.liuzk.com/405.html#comments Tue, 08 Oct 2019 04:37:55 +0000 http://www.liuzk.com/?p=405 建一个,txt文档,把下面的代码粘贴进去:

@echo off
(cd /d "%~dp0")&&(NET FILE||(powershell start-process -FilePath '%0' -verb runas)&&(exit /B)) >NUL 2>&1
title Office 2019 Activator r/Piracy
echo Converting... & mode 40,25
(if exist "%ProgramFiles%\Microsoft Office\Office16\ospp.vbs" cd /d "%ProgramFiles%\Microsoft Office\Office16")&(if exist "%ProgramFiles(x86)%\Microsoft Office\Office16\ospp.vbs" cd /d "%ProgramFiles(x86)%\Microsoft Office\Office16")&(for /f %%x in ('dir /b ..\root\Licenses16\ProPlus2019VL*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul)&(for /f %%x in ('dir /b ..\root\Licenses16\ProPlus2019VL*.xrm-ms') do cscript ospp.vbs /inslic:"..\root\Licenses16\%%x" >nul)
cscript //nologo ospp.vbs /unpkey:6MWKP >nul&cscript //nologo ospp.vbs /inpkey:NMMKJ-6RK4F-KMJVX-8D9MJ-6MWKP >nul&set i=1
:server
if %i%==1 set KMS_Sev=kms7.MSGuides.com
if %i%==2 set KMS_Sev=kms8.MSGuides.com
if %i%==3 set KMS_Sev=kms9.MSGuides.com
cscript //nologo ospp.vbs /sethst:%KMS_Sev% >nul
echo %KMS_Sev% & echo Activating...
cscript //nologo ospp.vbs /act | find /i "successful" && (echo Complete) || (echo Trying another KMS Server & set /a i+=1 & goto server)
pause >nul
exit

 

把文件名,改成 激活.bat

右键,选择“以管理员身份运行”,运行后会弹出黑色的控制台窗台,等待几十秒 或者更多,当出现 complete之后,表示已经已经激活完成。

这个是利用KMS的办法激活,至于里面的服务器,什么时候有效,还不一定,试过之后不行的话,出门右拐,找百度吧。

 

转载请注明:刘召考的博客 » Office 2019激活办法–亲试有效

]]>
http://www.liuzk.com/405.html/feed 0
小谈MapReduce http://www.liuzk.com/402.html http://www.liuzk.com/402.html#comments Mon, 30 Sep 2019 03:28:02 +0000 http://www.liuzk.com/?p=402 Hadoop 是Apache 下的一个项目,由HDFS、MapReduce、HBase、Hive 和ZooKeeper等成员组成。
HDFS:分布式存储系统
MapReduce:分布式计算系统
其中,HDFS 和MapReduce 是两个最基础最重要的成员。

InfoWord将MapReduce 评为2009 年十大新兴技术的冠军。MapReduce 是大规模数据(TB 级)计算的利器,Map 和Reduce 是它的主要思想,
来源于函数式编程语言,它的原理如下图所示:Map负责将数据打散,Reduce负责对数据进行聚集,用户只需要实现map 和reduce 两个接口,
即可完成TB级数据的计算,常见的应用包括:日志分析和数据挖掘等数据分析应用。另外,还可用于科学数据计算,如圆周率PI 的计算等。

Hadoop MapReduce的实现也采用了Master/Slave 结构。Master 叫做JobTracker,而Slave 叫做TaskTracker。
用户提交的计算叫做Job,每一个Job会被划分成若干个Tasks。JobTracker负责Job 和Tasks 的调度,而TaskTracker负责执行Tasks。

首先从Map端开始分析,当Map开始产生输出的时候,他并不是简单的把数据写到磁盘,因为频繁的写磁盘会导致性能严重下降,他的处理更加复杂,数据首先是写到内存中的一个缓冲区,并作一些预排序,以提升效率,每个Map任务都有一个用来写入输出数据的循环内存缓冲区,这个缓冲区默认大小是100M,可以通过io.sort.mb属性来设置具体的大小,当缓冲区中的数据量达到一个特定的阀值时,系统将会启动一个后台线程把缓冲区中的内容spill 到磁盘。在spill过程中,Map的输出将会继续写入到缓冲区,但如果缓冲区已经满了,Map就会被阻塞直道spill完成。spill线程在把缓冲区的数据写到磁盘前,会对他进行一个二次排序:
首先根据数据所属的partition排序,然后每个partition中再按Key排序。输出包括一个索引文件和数据文件,如果设定了Combiner,将在排序输出的基础上进行。Combiner就是一个Mini Reducer,它在执行Map任务的节点本身运行,先对Map的输出作一次简单的Reduce,使得Map的输出更紧凑,更少的数据会被写入磁盘和传送到Reducer。Spill文件保存在由mapred.local.dir指定的目录中,Map任务结束后删除。

Map的输出文件放置在运行Map任务的TaskTracker的本地磁盘上(注意:Map输出总是写到本地磁盘,但是Reduce输出不是,一般是写到HDFS),它是运行Reduce任务的 TaskTracker所需要的输入数据。Reduce任务的输入数据分布在集群内的多个Map任务的输出中,Map任务可能会在不同的时间内完成,只要有其中一个Map任务完成,Reduce任务就开始拷贝他的输出。这个阶段称为拷贝阶段,Reduce任务拥有多个拷贝线程,可以并行的获取Map输出。可以通过设定  mapred.reduce.parallel.copies来改变线程数。

Reduce是怎么知道从哪些TaskTrackers中获取Map的输出呢?当Map任务完成之后,会通知他们的父TaskTracker,告知状态更新,然后TaskTracker再转告JobTracker,这些通知信息是通过心跳通信机制传输的,因此针对以一个特定的作业,jobtracker知道Map输出与tasktrackers的映射关系。
Reducer中有一个线程会间歇的向JobTracker询问Map输出的地址,直到把所有的数据都取到。在Reducer取走了Map输出之后,TaskTracker不会立即删除这些数据,因为Reducer可能会失败,他们会在整个作业完成之后,JobTracker告知他们要删除的时候才去删除,如果Map输出足够小,他们会被拷贝到Reduce TaskTracker的内存中(缓冲区的大小由mapred.job.shuffle.input.buffer.percnet控制),或者达到了Map输出的阀值的大小(由mapred.inmem.merge.threshold控制),缓冲区中的数据将会被归并然后spill到磁盘。

拷贝来的数据叠加在磁盘上,有一个后台线程会将它们归并为更大的排序文件,这样做节省了后期归并的时间。对于经过压缩的Map 输出,系统会自动把它们解压到内存方便对其执行归并。

当所有的Map 输出都被拷贝后,Reduce 任务进入排序阶段(更恰当的说应该是归并阶段,因为排序在Map 端就已经完成),这个阶段会对所有的Map 输出进行归并排序,这个工作会重复多次才能完成。假设这里有50 个Map 输出(可能有保存在内存中的),并且归并因子是10(由io.sort.factor控制,就像Map 端的merge 一样),那最终需要5 次归并。每次归并会把10个文件归并为一个,最终生成5 个中间文件。在这一步之后,系统不再把5 个中间文件归并成一个,而是排序后直接“喂”给Reduce 函数,省去向磁盘写数据这一步。

最终归并的数据可以是混合数据,既有内存上的也有磁盘上的。由于归并的目的是归并最少的文件数目,使得在最后一次归并时总文件个数达到归并因子的数目,所以每次操作所涉及的文件个数在实际中会更微妙些。譬如,如果有40 个文件,并不是每次都归并10 个最终得到4 个文件,相反第一次只归并4 个文件,然后再实现三次归并,每次10 个,最终得到4 个归并好的文件和6 个未归并的文件。

要注意,这种做法并没有改变归并的次数,只是最小化写入磁盘的数据优化措施,因为最后一次归并的数据总是直接送到Reduce 函数那里。
在Reduce 阶段,Reduce 函数会作用在排序输出的每一个key 上。这个阶段的输出被直接写到输出文件系统,一般是HDFS。在HDFS 中,因为TaskTracker 节点也运行着一个DataNode 进程,所以第一个块备份会直接写到本地磁盘。到此,MapReduce 的Shuffle 和Sort 分析完毕。

转载请注明:刘召考的博客 » 小谈MapReduce

]]>
http://www.liuzk.com/402.html/feed 0
分库分表,你理解到什么程度呢? http://www.liuzk.com/380.html http://www.liuzk.com/380.html#comments Fri, 06 Sep 2019 10:48:45 +0000 http://www.liuzk.com/?p=380 随着互联网产业的蓬勃发展,在互联网应用上产生的数据也是与日俱增。产生大量的交易记录和行为记录,它们的存放和分析是我们需要面对的问题。例如:单表中出现了,动辄百万甚至千万级别的数据。“分表分库”就成为解决上述问题的有效工具。今天和大家一起看看,如何进行分表分库以及期间遇到的问题吧。

为什么会分表分库

数据库数据会随着业务的发展而不断增多,因此数据操作,如增删改查的开销也会越来越大。

再加上物理服务器的资源有限(CPU、磁盘、内存、IO 等)。最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

换句话说需要合理的数据库架构来存放不断增长的数据,这个就是分库分表的设计初衷。目的就是为了缓解数据库的压力,最大限度提高数据操作的效率。

数据分表

如果单表的数据量过大,例如千万级甚至更多,那么在操作表的时候就会加大系统的开销。

每次查询会消耗数据库大量资源,如果需要多表的联合查询,这种劣势就更加明显了。

以 MySQL 为例,在插入数据的时候,会对表进行加锁,分为表锁定和行锁定。

无论是哪种锁定方式,都意味着前面一条数据在操作表或者行的时候,后面的请求都在排队,当访问量增加的时候,都会影响数据库的效率。

那么既然一定要分表,那么每张表分配多大的数据量比较合适呢?这里建议根据业务场景和实际情况具体分析。

一般来说 MySQL 数据库单表记录最好控制在 500 万条(这是个经验数字)。既然需要将数据从一个表分别存放到多个表中,那么来看看下面两种分表方式吧。

垂直分表

根据业务把一个表中的字段(Field)分到不同的表中。这些被分出去的数据通常根据业务需要,例如分出去一些不是经常使用的字段,一些长度较长的字段。

一般被拆分的表的字段数比较多。主要是避免查询的时候出现因为数据量大而造成的“跨页”问题。

一般这种拆分在数据库设计之初就会考虑,尽量在系统上线之前考虑调整。已经上线的项目,做这种操作是要慎重考虑的。

水平分表

将一个表中的数据,按照关键字(例如:ID)(或取 Hash 之后)对一个具体的数字取模,得到的余数就是需要存放到的新表的位置。

1

用 ID 取模的分表方式分配记录

ID 分别为 01-04 的四条记录,如果分配到 3 个表中,那么对 3 取模得到的余数分别是:

  • ID:01 对 3 取模余数为 1 ,存到“表 1”。
  • ID:02 对 3 取模余数为 2 ,存到“表 2”。
  • ID:03 对 3 取模余数为 3 ,存到“表 3”。
  • ID:04 对 3 取模余数为 1 ,存到“表 1”。

当然这里只是一个例子,实际情况需要对 ID 做 Hash 之后再计算。同时还可以针对不同表所在的不同的数据库的资源来设置存储数据的多少。针对每个表所在的库的资源设置权值。

用这种方式存放数据以后,在访问具体数据的时候需要通过一个 Mapping Table 获取对应要响应的数据来自哪个数据表。目前比较流行的数据库中间件已经帮助我们实现了这部分的功能。

也就是说不用大家自己去建立这个 Mapping Table,在做查询的时候中间件帮助你实现了 Mapping Table 的功能。所以,我们这里只需要了解其实现原理就可以了。

2

水平拆分还有一种情况是根据数据产生的前后顺序来拆分存放。例如,主表只存放最近 2 个月的信息,其他比较老旧的信息拆分到其他的表中。通过时间来做数据区分。更有甚者是通过服务的地域来做数据区分的。

3

需要注意的是由于分表造成一系列记录级别的问题,例如 Join 和 ID 生成,事务处理,同时存在这些表需要跨数据库的可能性:

  • Join:需要做两次查询,把两次查询的结果在应用层做合并。这种做法是最简单的,在应用层设计的时候需要考虑。
  • ID:可以使用 UUID,或者用一张表来存放生成的 Sequence,不过效率都不算高。UUID 实现起来比较方便,但是占用的空间比较大。Sequence 表的方式节省了空间,但是所有的 ID 都依赖于单表。这里介绍一个大厂用的 Snowflake 的方式。

Snowflake 是 Twitter 开源的分布式 ID 生成算法,结果是一个 long 型的 ID。

其核心思想是:使用 41bit 作为毫秒数,10bit 作为机器的 ID(5 个 bit 是数据中心,5 个 bit 的机器 ID),12bit 作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是 0。

4

排序/分页:数据分配到水平的几个表中的时候,做排序和分页或者一些集合操作是不容易的。

这里根据经验介绍两种方法。对分表的数据先进行排序/分页/聚合,再进行合并。对分表的数据先进行合并再做排序/分页/聚合。

事务:存在分布式事务的可能,需要考虑补偿事务或者用 TCC(Try Confirm Cancel)协助完成,这部分的内容我们下面会为大家介绍。

数据分库

说完了分表,再来谈谈分库。每个物理数据库支持数据都是有限的,每一次的数据库请求都会产生一次数据库链接,当一个库无法支持更多访问的时候,我们会把原来的单个数据库分成多个,帮助分担压力。

这里有几类分库的原则,可以根据具体场景进行选择:

  • 根据业务不同分库,这种情况都会把主营业务和其他功能分开。例如可以分为订单数据库,核算数据库,评论数据库。
  • 根据冷热数据进行分库,用数据访问频率来划分,例如:近一个月的交易数据属于高频数据,2-6 个月的交易数据属于中频数据,大于 6 个月的数据属于低频数据。
  • 根据访问数据的地域/时间范围进行分库。

5

通常数据分库之后,每一个数据库包含多个数据表,多个数据库会组成一个 Cluster/Group,提高了数据库的可用性,并且可以把读写做分离。

Master 库主要负责写操作,Slave 库主要负责读操作。在应用访问数据库的时候会通过一个负载均衡代理,通过判断读写操作把请求路由到对应的数据库。

如果是读操作,也会根据数据库设置的权重或者平均分配请求。另外,还有数据库健康监控机制,定时发送心跳检测数据库的健康状况。

如果 Slave 出现问题,会启动熔断机制停止对其的访问;如果 Master 出现问题,通过选举机制选择新的 Master 代替。

6

 

数据库扩容

分库之后的数据库会遇到数据扩容或者数据迁移的情况。这里推荐两种数据库扩容的方案。

主从数据库扩容

我们这里假设有两个数据库集群,每个集群分别有 M1 S1 和 M2 S2 互为主备。

7

 

由于 M1 和 S1 互为主备所以数据是一样的,M2 和 S2 同样。把原有的 ID %2 模式切换成 ID %4 模式,也就是把两个数据集群扩充到 4 个数据库集群。

负载均衡器直接把数据路由到原来两个 S1 和 S2 上面,同时 S1 和 S2 会停止与 M1 和 M2 的数据同步,单独作为主库(写操作)存在。

这些修改不需要重启数据库服务,只需要修改代理配置就可以完成。由于 M1 M2 S1 S2 中会存在一些冗余的数据,可以后台起服务将这些冗余数据删除,不会影响数据使用。

8

此时,再考虑数据库可用性,将扩展后的 4 个主库进行主备操作,针对每个主库都建立对应的从库,前者负责写操作,后者负责读操作。下次如果需要扩容也可以按照类似的操作进行。

9

双写数据库扩容

在没有数据库主从配置的情况下的扩容,假设有数据库 M1 M2 如下图:

10

需要对目前的两个数据库做扩容,扩容之后是 4 个库如下图。新增的库是 M3,M4 路由的方式分别是 ID%2=0 和 ID%2=1。

11

这个时候新的数据会同时进入 M1 M2 M3 M4 四个库中,而老数据的使用依旧从 M1 M2 中获取。

与此同时,后台服务对 M1 M3,M2 M4 做数据同步,建议先做全量同步再做数据校验。

12

当完成数据同步之后,四个库的数据保持一致了,修改负载均衡代理的配置为 ID%4 的模式。此时扩容就完成了,从原来的 2 个数据库扩展成 4 个数据库。

当然会存在部分的数据冗余,需要像上面一个方案一样通过后台服务删除这些冗余数据,删除的过程不会影响业务。

13

转载请注明:刘召考的博客 » 分库分表,你理解到什么程度呢?

]]>
http://www.liuzk.com/380.html/feed 0
JAudiotagger读取/修改音乐文件的属性信息 http://www.liuzk.com/374.html http://www.liuzk.com/374.html#comments Thu, 29 Aug 2019 02:43:57 +0000 http://www.liuzk.com/?p=374 最近需要用java读取音频文件(mp3,flac格式的文件)的详细属性信息,比如:包括采样率(SampleRate)、制作格式或制作技术(Format)、单曲名(TITLE)、单曲艺术家(ARTIST)、专辑名(ALBUM)、专辑艺术家(ALBUM_ARTIST)、音轨号(TRACK)、语言(LANGUAGE)、版权方(COPYRIGHT)等等,并统一修改。研究了好久,发现有个第三方的开源jar,很好用。

JAudiotagger

官网地址:http://www.jthink.net/jaudiotagger

API DOC:http://www.jthink.net/jaudiotagger/javadoc/index.html

下载地址:https://repo1.maven.org/maven2/org/jaudiotagger/2.0.3/

使用示例:

使用起来,很简单,读取MP3文件的Title和歌唱家属性,并修改:

private void readMP3File(File file){
        String fileName = file.getName();
        if(!fileName.endsWith(".MP3") && !fileName.endsWith(".mp3")){
            return;
        }

        /**
         * 自定义 标题  作者  专辑
         */
        String _author = "周杰伦";
        String _title = "青花瓷";
        String _album = "《范特西》";

        MP3FileReader reader = new MP3FileReader();
        try {
            AudioFile audioFile = reader.read(file);
            Tag tag = audioFile.getTag();

            boolean update = false;
            String ARTIST = tag.getFirst(FieldKey.ARTIST);
            if(StringUtils.isEmpty(ARTIST) ){
                tag.setField(FieldKey.ARTIST,_author);
                update = true;
            }
            String TITLE = tag.getFirst(FieldKey.TITLE);
            if(StringUtils.isEmpty(TITLE) ){
                tag.setField(FieldKey.TITLE,_title);
                update = true;
            }
            String ALBUM = tag.getFirst(FieldKey.ALBUM);
            if(StringUtils.isEmpty(ALBUM) ){
                tag.setField(FieldKey.ALBUM,_album);
                update = true;
            }
            /**
             * 如果有修改,写入文件
             */
            if(update){
                MP3FileWriter writer = new MP3FileWriter();
                writer.writeFile(audioFile);
            }


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

同样,对于无损音乐文件也是一样的使用方式,只是,把Reader类 和 Writer类换成Flac的封装:

FlacFileReader reader = new FlacFileReader();
AudioFile audioFile = reader.read(file);
Tag tag = audioFile.getTag();

 

FlacFileWriter writer = new FlacFileWriter();
writer.write(audioFile);

 

对于其他的属性和信息,大家可以参考官方文档。

参考文章:https://www.cnblogs.com/once/p/3734755.html

 

转载请注明:刘召考的博客 » JAudiotagger读取/修改音乐文件的属性信息

]]>
http://www.liuzk.com/374.html/feed 0