使用Docker Compose一键部署前后端分离项目

目录 一、安装Docker和docker Compose (1)Docker安装 (2)Docker Compose安装 (3)查看版本信息 二、准备工作 1. 新建工作目录 2. 工作目录结构 3. 后台打包 4. 前台打包 5. 数据库文件上传 6. 编写Dockerfile (1)mysql-dockerfile (2)nginx-dockerfile (3)redis-dockerfile (4)ruoyi-dockerfile 7. 编写 docker-compose.yml 文件 8. 构建并启动 (1)构建docker服务 (2)启动docker容器 (3)查看容器 (4)浏览器访问测试 前面的博客介绍了使用 Docker 部署前后端分离项目:使用Docker部署前后端分离项目 接下来介绍如何使用 Docker Compose部署前后端分离项目,依旧以若依项目为例。 一、安装Docker和docker Compose (1)Docker安装 [root@zy-host /]# yum install -y yum-utils device-mapper-persistent-data lvm2 [root@zy-host /]# yum install docker-ce docker-ce-cli containerd.io (2)Docker Compose安装 [root@zy-host home]# curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose [root@zy-host home]# chmod +x /usr/local/bin/docker-compose (3)查看版本信息 [root@zy-host home]# docker --version Docker version 20.

DIY可视化打造的基于vue+uniapp下拉气泡组件

下拉气泡组件在使用场景里非常常用,比较快速分类选择、点击弹出操作按钮等,DIY可视化支持自定义下拉气泡组件里的内容,达到非常灵活的气泡效果而不单一。 最常见微信里右上角三个点 => 展开下拉菜单 => 点击下拉菜单的某个功能 进入功能界面。 <template> <view v-if="visibleSync" :style="[customStyle, { zIndex: uZindex - 1 }]" class="diy-popover" hover-stop-propagation> <u-mask :blur="blur" :duration="duration" :custom-style="maskCustomStyle" :maskClickAble="maskCloseAble" :z-index="uZindex - 2" :show="showDrawer && mask" @click="maskClick"></u-mask> <!-- 移除 @tap.stop.prevent --> <view class="popover" :class="[ safeAreaInsetBottom ? 'safe-area-inset-bottom' : '', showDrawer ? 'diy-popover-visible' : '' ]" @touchmove.stop.prevent :style="{width:width,background:diybgcolor,'--arrow-color':diybgcolor,top: popoverTop ,left: popoverLeft}"> <text :class="['popover-'+diymode,'popover-'+dynPlace]" :style="{width:'0px',height:'0px'}"></text> <slot></slot> </view> </view> </template> <script> /** * popover 汽泡组件 * @description 汽泡组件,用于汽泡组件、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义 * @property {String} mode 弹出方向(默认left) * @property {Boolean} mask 是否显示遮罩(默认true) * @property {Stringr | Number} length mode=top * @property {Boolean} zoom 是否开启缩放动画,只在mode为center时有效(默认true) * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false) * @property {Boolean} mask-close-able 点击遮罩是否可以关闭弹出层(默认true) * @property {Numberr | String} z-index 弹出内容的z-index值(默认1075) * @event {Function} open 弹出层打开 * @event {Function} close 弹出层收起 */ export default { name: 'diy-popover', emits: ["

python 3 添加环境变量后 仍然无法用cmd输入python访问,而是弹出应用商店 | 两种解决方法

问题描述 今天重装python3.10后发现即使正确添加环境变量时,仍然无法用cmd输入python或python3访问,而是弹出应用商店。但是如果输入cmd里输入py是可以运行的(证明python是正常安装好的)。 这里给出两种解决方法,一种方法不行就双管齐下,一劳永逸。 解决方法 1 网上给出的答案是:因为默认的商店的path环境变量优先级高于我们配置的python目录。 这里有一篇博客讲的很清楚: 方法我用了,但是没啥用啊?!python的环境变量置顶但是cmd打开的仍然是应用商店。。。。 这时候就要用方法2了。 解决方法 2 在开始菜单中搜索 Manage app execution aliases 把 App Installer 的python.exe 和 python3.exe 关了! 关掉这两个B后,我的cmd能用python打开了。你的呢 原因(知识补充): Windows会在名为 %USERPROFILE%\AppData\Local\Microsoft\WindowsApps 的目录中放置一个名为python.exe和python3.exe的空文件或假文件 (坏B)。 导致虽然有时候调整了环境变量顺序,仍然无法用python打开的情况。 另外在 Sublime Text 3 中运行python程序时会如出现下图报错,并给出解决方案。 Reference https://stackoverflow.com/questions/58754860/cmd-opens-windows-store-when-i-type-pythonhttp://t.csdn.cn/2oWaq 以上。

React Hooks 基础、实现、原理

React Hooks 基础、实现、原理 题外话为什么要有Hooks?但是Class Component 的用法也有缺陷:1.组件复用变的困难2.JavaScript本身的缺陷 函数式 React HooksuseStateuseEffectuseCallback、useMemouseReducer 最后 题外话 2023了,新年快乐!转眼间就已经工作一年左右了,这一年提升很多,想到很久没有整理知识点了所以… 为什么要有Hooks? 官方给出的解释是:复杂组件变得难以理解、组件之间复用状态逻辑很难 React是以组件为粒度编排应用的,组件是代码复用的最小单元。 在设计上,React采用props属性来接收外部的数据,使用state属性来管理组件自身产生的数据(状态),也就是说props 是传递给组件的(类似于函数的形参),而 state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)。而为了实现(运行时)对数据变更做出响应需要,React采用基于类(Class)的组件设计。除此之外,React认为组件是有生命周期的。 但是Class Component 的用法也有缺陷: 1.组件复用变的困难 HOC是React中用于重用组件逻辑的一种高级技术实现模式,它本身是一个函数,接受一个组件并返回一个新的组件。 而HOC容易产生嵌套地狱,每一次HOC调用都会产生一个组件实例。 2.JavaScript本身的缺陷 稍微不慎就会出现因this的指向报错。没有类似Java/C++多继承的概念,类的逻辑复用是个问题。 函数式 当然React不只是只有类式写法,还有函数式,但是早期的函数式组件只是单纯地接收props、绑定事件、返回jsx,本身是无状态的组件,依赖props传入的handle来响应数据(状态)的变更,所以函数式组件不能脱离Class Comnent来存在。 这时候就诞生了Hook,使得组件自身能够通过某种机制再触发状态的变更并且引起re-render React Hooks useState useState可以管理组件自身定义的状态,返回一个 state,以及更新 state 的函数。 如下:setCount函数用于更新 count,它接收一个新的 state 值并将组件的一次重新渲染加入队列,并且引起组件re-render。在组件在初始渲染期间,返回的状态 (state) 与传入的第一个参数值相同也就是0。 并且count只能通过setCount来改变。 import React, { useState } from 'react'; function Add() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } dispatchAction函数是更新state的关键,它会生成一个update挂载到Hooks队列上面,并提交一个React更新调度,后续的工作和类组件一致。

linux下编译安装protobuf

文章目录 linux下编译安装protobuf1.下载protobuf源码2.解压缩3.配置configure4.编译并安装5.设置环境变量 linux下源码编译安装方法方法一方法二 linux下编译安装protobuf 1.下载protobuf源码 protobuf源码网址: https://github.com/google/protobuf/releases 在官网上选择对应的版本下载,压缩包下载可以在线下载之后本地安装,或者在终端通过wget指令下载 wget https://github.com/protocolbuffers/protobuf/releases/download/v3.13.0/protobuf-all-3.13.0.tar.gz 注意:在linux下,可以在home目录下单独建一个文件夹,用来保存各种源码,将编译好的内容放到 /usr/local/ 下面 linux源码编译安装过程一般为配置(configure)、编译(make)、安装(install)三部分,对下载的压缩包,要进行解压缩得到文件夹,配置安装路径后,借助make工具编译并安装。 2.解压缩 tar -zxvf protobuf-all-3.13.0.tar.gz 执行该命令,在压缩包同级目录下会看到解压缩得到的文件夹,这里我对文件夹利用mv命令进行重命名 mv protobuf-3.20.3 protobuf 结果如下图所示 3.配置configure 得到解压缩后的源码后,就要对安装路径进行配置,这里配置过程利用可执行脚本configure来完成,可执行脚本configure就在protobuf文件夹中。 通过指令./configure -help可查看配置选项,这里主要用--prefix指定安装路径。 ./configure --prefix=/usr/local/protobuf 如果不指定安装路径,源码会被编译安装在默认路径下 可执行文件:/usr/local/bin 库文件:/usr/local/lib 配置文件:/usr/local/etc 其他资源文件:/usr/local/share 通过上面指令指定安装路径后,在/usr/local/protobuf下会看到bin、include、lib三个文件夹,分别放置可执行文件与库文件 4.编译并安装 依次执行以下命令即可,执行make命令,运行makefile文件,makefile文件指令编译与链接规则,之后执行make install命令,该命令会将protobuf安装到指定路径下。ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。安装完成后执行ldconfig命令。 make make install ldconfig 注意,这段时间需要编译源码,等待时间较长。 5.设置环境变量 在 Linux 系统中,环境变量是用来定义系统运行环境的一些参数,其中环境变量PATH指明命令行解释器搜索用户执行命令的路径,为了保证在系统任何目录下都能使用protoc命令,需要在配置文件中添加相关变量 包括动态库搜索路径、静态库搜索路径、执行程序搜索路径等,添加过程很简单,利用vi 指令打开/etc/profile文件,在文件末尾添加下面的内容,之后更新环境变量。 #protobuf config #(动态库搜索路径) 程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib/ #(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径 export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib/ #执行程序搜索路径 export PATH=$PATH:/usr/local/protobuf/bin/ #c程序头文件搜索路径 export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/ #c++程序头文件搜索路径 export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/ #pkg-config 路径 export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/ vi /etc/profile source /etc/profile 最后,执行protoc --version查看protobuf安装的版本,用来检验是否安装成功。

python|if语句必备基础知识

目录 一、使用and检查多个条件 二、使用or检查多个条件 三、关键字in判断是否在列表中 四、关键字not in判断是否在列表中 五、对列表使用if语句 六、往期内容 一、使用and检查多个条件 作用:多个条件同时满足则为真,只要有1个不满足则为假。 例子代码: a = 6 if a>5 and a<8: print('yes') else: print('no') 运行结果: yes 二、使用or检查多个条件 作用:只要有1个满足则为真,所有条件都不满足时则为假。 例子代码: a = 6 if a<5 or a>8: print('yes') else: print('no') 运行结果: no 三、关键字in判断是否在列表中 作用:判断某个值是否在列表中。 例子代码: a = 3 numbers14 = [1,2,3] if a in numbers14: print('yes') else: print('no') 运行结果: yes 四、关键字not in判断是否在列表中 作用:判断某个值是否不在列表中。 例子代码: a = 4 if a not in numbers14: print('yes') else: print('no') 运行结果:

如何将list中的某个元素移动到指定位置,java

如果你想将列表中的某个元素移动到指定位置,可以使用以下方法之一: 在列表中删除该元素,然后使用 add() 方法将其插入到指定位置。例如: List<String> list =new ArrayList<>(Arrays.asList("apple", "banana", "cherry")); int index = 1; String element = "mango"; list.remove(element); list.add(index, element);

java入门之接口----以电脑USB为灯供电为例

接口简述: 接口可以简单理解为规范,规则。接口是一种特殊的类。 代码格式: interface 接口名{ 规则属性,规则的行为 } 规则属性为常量,接口行为是抽象方法。 接口性质: 所谓的接口,可以简单理解为规则 基本语法: interface接口名称规则属性,规则的行为子 接口其实是抽象的 规则的属性必须为固定值,而且不能修改 属性和行为的访问权限必须为公共的 属性应该是静态的 行为应该是抽象的 接口和类是两个层面的东西 接可以继承其他接口 类的对象需要遵循接口,在 Java 中,这个遵循,称之为实现(implements),类需要实现接口,而且可以实现多个接口。 接口代码: 首先声明一个USB接口: interface USBInterface{ } USB接口可以提供服务,也可以接受服务,这两个功能是: //提供功能 interface USBsupply extends USBInterface{ public void powersupply(); } //接受功能 interface USBreceive extends USBInterface{ public void powerreceive(); } 电脑可以提供两个USB接口 ,实现了USB提供服务的规范: class computer implements USBsupply{ public USBreceive usb1; public USBreceive usb2; public void powersupply(){ System.out.println("电脑提供电源"); usb1.powerreceive();//设备一接受能源 usb2.powerreceive();//设备二接受能源 } } 台灯的USB实现了接受服务的规范: class light implements USBreceive{ public void powerreceive(){ System.

int,long,long long对应10的数量级【c语言】

刷题的时候,题目会给出变量的范围,这个时候就要想清楚用哪个类型 #include<iostream> using namespace std; int main(){ int d2 = (1<<31)-1; int d0 = 10; long l2 = ((long)1<<31)-1; long l0 = 10; long long ll2 = ((long long)1<<63)-1; long long ll0 = 10; for(int i = 0; i<8; i++) d0*=10;//即10^9 for(int i = 0; i<8; i++) l0*=10;//即10^9 for(int i = 0; i<17; i++) ll0*=10;//即10^18 cout<< d2 << " (int的最大值)" <<endl; cout<< d0 << " (对应10^9)" <<endl; cout<< l2 << "

RocketMQ(七)broker接收消息入口源码

此前梳理了RocketMQ的Producer发送消息的源码,首先会查找topic的发布信息,然后找到一个消息队列MessageQueue,默认是轮询的选择,MessageQueue中存储着对应的brokerName,通过brokerName就能找到具体的brokerIP,随后获取Producer客户端与这台broker的channel,随后就可以向这台broker发送消息了,注意消息只会被发送到主broker中,即Master节点。 以上就是RocketMQ的Producer发送消息的大概流程,下面接着看RocketMQ的broker接收消息,处理请求的源码。 1 broker处理请求入口 1.1 registerProcessor注册消息处理器 RocketMQ的各种组件的网络通信都是基于Netty实现的, 我们在此前梳理RocketMQ的broker的启动源码的时候,会发现broker在启动的时候在brokerController#registerProcessor方法中会注册很多的netty消息处理器,不同的消息处理器可以处理不同的消息类型。 /** * BrokerController的方法 * 注册netty消息处理器 * * 从这里的源码能够看出来,除了pullMessageProcessor处理器只会被注册到remotingServer之外, * 其他处理器会被注册到remotingServer和fastRemotingServer这两个netty服务中。 * * 所以Vip通道服务不能够处理拉取消息的请求 */ public void registerProcessor() { /* * SendMessageProcessor */ /** * 发送消息处理器 */ sendMessageProcessor.registerSendMessageHook(sendMessageHookList); sendMessageProcessor.registerConsumeMessageHook(consumeMessageHookList); //对于发送类型的请求,使用发送消息处理器sendProcessor来处理 this.remotingServer.registerProcessor(RequestCode.SEND_MESSAGE, sendMessageProcessor, this.sendMessageExecutor); this.remotingServer.registerProcessor(RequestCode.SEND_MESSAGE_V2, sendMessageProcessor, this.sendMessageExecutor); this.remotingServer.registerProcessor(RequestCode.SEND_BATCH_MESSAGE, sendMessageProcessor, this.sendMessageExecutor); this.remotingServer.registerProcessor(RequestCode.CONSUMER_SEND_MSG_BACK, sendMessageProcessor, this.sendMessageExecutor); this.fastRemotingServer.registerProcessor(RequestCode.SEND_MESSAGE, sendMessageProcessor, this.sendMessageExecutor); this.fastRemotingServer.registerProcessor(RequestCode.SEND_MESSAGE_V2, sendMessageProcessor, this.sendMessageExecutor); this.fastRemotingServer.registerProcessor(RequestCode.SEND_BATCH_MESSAGE, sendMessageProcessor, this.sendMessageExecutor); this.fastRemotingServer.registerProcessor(RequestCode.CONSUMER_SEND_MSG_BACK, sendMessageProcessor, this.sendMessageExecutor); /** * PullMessageProcessor */ this.remotingServer.registerProcessor(RequestCode.PULL_MESSAGE, this.pullMessageProcessor, this.pullMessageExecutor); this.remotingServer.registerProcessor(RequestCode.LITE_PULL_MESSAGE, this.

TS高级类型

TS中的高级类型有很多 重点学习一下高级类型: class类 类型兼容性 交叉类型 泛型和keyof 索引签名类型和索引查询类型 映射类型 class类 TS全面知识ES6中引入的class关键字 并为其添加了类型注解和其他语法(比如,可见性修饰符等) class基本使用: class Person{} const p=new Person() 解释: 根据TS中的类型推论 可以知道Person类的实例对象p的类型是Person TS中的class 不仅提供了class的语法功能 也作为一种类型存在 示例属性初始化: class Person { age:number gender='男' //gender:string='男' } 解释: 声明成员age 类型为number (没有初始值) 声明成员gender 并设置初始值 此时 可省略类型注解(TS类型推论为string类型) class Person { age:number gender:string constructor(age:number,gender:string){ this.age=age this.gender=gender } } 解释: 成员初始化(比如 age:number)后,才可以通过this.age来访问实例成员 需要为构造函数指定类型注解,否则会被隐式推断为any,构造函数不需要返回值类型 class Point { x=10 y=10 fn(n:number):void{ this.x*=n this.y*=n } } 解释: 方法的类型注解(参数和返回值)与函数用法相同 类继承的两种方式: extends(继承父类) implements(实现接口) 说明:JS中只有extends 而iimplements是TS提供的 通过 extends(继承父类) class Animal{ move(){console.

git中pull和fetch的区别是什么

git中pull和fetch的区别是什么 Git Fetch 将更新git remote 中所有的远程repo 所包含分支的最新commit-id, 将其记录到.git/FETCH_HEAD文件中 git pull 基于本地的FETCH_HEAD记录,比对本地的FETCH_HEAD记录与远程仓库的版本号,然后git fetch 获得当前指向的远程分支的后续版本的数据,然后再利用git merge将其与本地的当前分支合并。 git pull 等效于先执行 git fetch origin 当前分支名, 再执行 git merge FETCH_HEAD. Git fetch和git pull区别为:远端跟踪分支不同、拉取不同、commitID不同。 一、远端跟踪分支不同 1、Git fetch:Git fetch能够直接更改远端跟踪分支。 2、git pull:git pull无法直接对远程跟踪分支操作,我们必须先切回本地分支然后创建一个新的commit提交。 二、拉取不同 git pull:拉取。即从远程仓库拉取最新版本文件到本地,自动合并/merge。 git fetch:抓取,获取。即从远程获取最新版本文件到本地,不自动合并/merge。 三、commitID不同 1、Git fetch:使用Git fetch更新代码,本地的库中master的commitID不变,还是等于1。 2、git pull:使用git pull更新代码,本地的库中master的commitID发生改变,变成了2。

Linux中usleep和sleep区别详解!

在Linux系统中,usleep和sleep是比较常见的两种睡眠时间函数,而且从名字上来看,两个函数仅有一个字母之差,那么Linux中usleep和sleep区别是什么?以下是详细的内容介绍。 1、sleep()——以秒为单位 头文件: #includ // 在VC中使用带上头文件 #include // 在gcc编译器中,使用的头文件因gcc版本的不同而不同 功能:执行挂起指定的秒数 语法: unsigned int sleep(unsigned int seconds); sleep()非系统调用,sleep()是在库函数中实现的,它是通过alarm()来设定报警时间,使用sigsuspend()将进程挂起在信号SIGALARM上。 sleep()只能精确到秒级上。sleep()会令目前的进程暂停,直到达到参数seconds所指定的时间,或是被信号所中断。 #include return:若进程暂停到参数seconds所指定的时间,成功则返回0.若有信号中断则返回剩余秒数。 2、usleep()——以微秒为单位 头文件: #include 功能:usleep功能把进程挂起一段时间,单位是微秒。 语法: void usleep(int micro_seconds); 除了时间单位为微秒以外,在使用上与sleep()差不多。还有就是实现也是不同的,sleep因为是用alarm实现的,所以时间单位为s,而usleep的时间单位为us,那肯定不是由alarm实现的,所以说它们的实现不同,但都是Linux用的,而Window下不能用,因为都是sleep和usleep都是在unistd.h下定义的。 #include return:若进程暂停到参数seconds所指定的时间,成功则返回0.若有信号中断则返回剩余微秒数。 返回值:无 内容说明:本函数可暂时使程序停止执行。参数micro_seconds为要暂停的微秒数。

React循环遍历渲染数组对象

我们就做个最基本得案例,底部导航栏 我们在seate里面定义数组 state = { list: [ { id: 1, text: '首页' }, { id: 2, text: '分类' }, { id: 3, text: '我的' }, ], nav: 1 } react得循环渲染跟vue不一样,vue咱们都是用里面封装好的的方法,而react用的是原生js map 方法来实现循环渲染数据的。这就跟别人常说的,react若无需要,勿增实例。 // 内容 <div className='body'> {this.which()} </div> // 底部导航栏 <div className='nav_header'> {this.state.list.map((item, index) => <div key={index} className={this.state.nav == item.id ? 'active' : ''} onClick={() => { // 通过点击事件去给 this.state.nav 重新赋值 this.state.nav = item.id this.setState({ // 更改底部导航选中状态 nav: this.state.nav }) }}> <span className='btn'>{item.

uni-app的常用 使用指南

uni-app中常用功能记录 1、加载动画 显示消息提示框 自带api功能 https://uniapp.dcloud.io/api/ui/prompt?id=showloading uni.showLoading({ //开启动画 title: '加载中' //动画提示文字 }); setTimeout( () =>{ uni.hideLoading(); //动画关闭 }, 2000); // 显示消息提示框。 uni.showToast({ title: '标题', duration: 2000 }); 2、宫格布局 组件宫格布局 https://uniapp.dcloud.io/component/uniui/uni-grid 修改shadow内的item即可修改宫格每一项的样式 .uni-grid-item { //修改该样式的高度可设置宫格内部的样式 height: 80px !important; } 3、页面下拉加载和上拉刷新 来自页面周期函数 用户上拉到顶部以上,执行周期函数,进行刷新操作 需要在 pages.json 里,找到的需要下拉刷新页面的pages节点,并在 style 选项中开启 enablePullDownRefresh 在页面page的style中添加 "enablePullDownRefresh":true 在页面page的mounted 同级别中添加周期函数 onPullDownRefresh(){ // 代码块 } --------------------------------------------------------------------------------------------------------------- 用户下拉到底部,执行周期函数,加载操作 在页面中添加周期函数 onReachBottom(){ 代码块 } 4、点击弹出模态确认框 来自uni.showModal方法 https://uniapp.dcloud.io/api/ui/prompt?id=showmodal 方法一: 直接在点击事件中添加 ​ uni.showModal({ ​ title: ‘是否确认清空所有收藏’, //模态框标题 ​ content: ‘清空收藏后无法恢复’, //提示文字 ​ success: (res) => { ​ if (res.

Mysql全文索引

1.背景简介 项目开发过程有时候会遇到全文检索的需求,但是数据量有时候比较小,不属于高并发高吞吐场景,这种场景搭建ES服务有点浪费资源,也把工程设计复杂了,所以需要采用更简单更廉价的方案。一般业务系统都会用到Mysql或者PostgreSQL服务,无论是Mysql还是PostgreSQL都对full-text做了兼容,下面以最常见的mysql数据库服务为例,讲述mysql服务接入full-text索引的过程。 2.Mysql全文索引简介 mysql的全文索引主要用于全文字段的检索场景,支持char、varchar、text几个字段加全文索引,仅支持InNoDB与MyISAM引擎。 mysql内置了ngram解析器来支持中文、日文、韩文等语言的文本,全文索引支持通过建表语句来创建或者建表后新增。 mysql全文索引支持三种模式: ● 布尔模式(IN BOOLEAN MODE) ● 自然语言模式(NATURAL LANGUAGE MODE) ● 查询拓展(QUERY EXPANSION) 参考: https://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html《Full-Text Search Functions》 3.ngram简介 ngram一种基于统计语言模型的算法,简单来说,就是通过一个大小为n的滑动窗口,将一段文本分成多个由n个连续单元组成的term。例: n=2 text=湖北省武汉市 经过ngram解析器解析后,得到如下分词: 湖北 北省 省武 武汉 汉市 ngram全文解析器是mysql服务内置的插件,与其他插件一样,在mysql服务启动的时候自动加载。 参考: https://zhuanlan.zhihu.com/p/32829048《自然语言处理中N-Gram模型介绍》 https://dev.mysql.com/doc/refman/5.7/en/fulltext-search-ngram.html《ngram Full-Text Parser》 4.数据库配置 先看mysql版本 ngram解析器是mysql5.7版本后,内置的全文索引解析器,所以要求mysql版本要5.7及以上。 查看mysql版本: select version() 配置ngram ngram可以作为启动字符串的一部分或者在配置文件中设置 启动字符串: mysqld --ngram_token_size=2 配置文件(my.ini): 以windos系统为例,首先找到my.ini文件(默认安装路径:C:\ProgramData\MySQL\MySQL Server 5.7\my.ini),编辑该文件,在文件后加上如下配置: ngram_token_size=2 配置完成后重启服务 5.创建全文索引 通过建表语句创建 CREATE TABLE `news` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容', `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题', PRIMARY KEY (`id`) USING BTREE, FULLTEXT INDEX `idx_full_text`(`content`) WITH PARSER `ngram` ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 通过CREATE FULLTEXT INDEX语句创建

hive调优总结

不定期更新 一、参数优化 参数 说明 set hive.exec.dynamic.partition=true 是否开启动态分区功能,默认false关闭。 set hive.exec.dynamic.partition.mode=nonstrict 动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。 set hive.exec.max.dynamic.partitions=1000000 在所有执行MR的节点上,最大一共可以创建多少个动态分区。 set hive.exec.max.dynamic.partitions.pernode=1000000 在每个执行MR的节点上,最大可以创建多少个动态分区 set hive.merge.mapfiles = true map-only job后合并文件 set hive.merge.mapredfiles = true map reduce job 后合并文件 set hive.merge.size.per.task = 250000000 合并后每个文件的大小 set hive.merge.smallfiles.avgsize=200000000 平均文件大小,是决定是否执行合并操作的阈值 set hive.exec.parallel=true 参数控制在同一个sql中的不同的job是否可以同时运行,默认false set mapred.job.parallel.thread.number=8 控制对于同一个SQL来说同时可以运行job的最大值 set mapred.job.reuse.jvm.num.tasks=8 因为 Hive 语句最终要转换为一系列的MapReduce Job 的,而每一个 MapReduceJob是由一系列的MapTask 和ReduceTask 组成的,默认情况下,MapReduce 中一个MapTask 或者一个ReduceTask 就会启动一个JVM进程,一个Task 执行完毕后,JVM进程就退出。这样如果任务花费时间很短,又要多次启动JVM 的情况下,JVM 的启动时间会变成一个比较大的消耗,这个时候,就可以通过重用JVM 来解决.(这个功能的一个缺点就是会一 直占用task插槽不释放,以备重用,直到任务完成才释放。如果在任务过程中出现数据倾斜,则可能task插槽需要等到reduce task任务完成才能释放) 二、SQL写法优化 减少count distinct 在使用count 和distinct的时候,每次使用都会调用一个reduce任务来完成,一个reduce任务如果处理的数据量过大会导致整个job难以完成。 避免:

原生js实现图片懒加载

1.什么是图片懒加载 图片懒加载就是鼠标滑动到哪里,图片加载到哪里。总的来说,一般页面打开,会同时加载页面所有的图片,如果页面的图片请求太多会造成很卡很慢的现象,为了避免这一现象,利用懒加载图片的方法,提高性能(典型:淘宝) 2. 实现图片懒加载的原理 图片懒加载的实现原理:将图片的地址放在data-set属性中,由于图片并没有在src中,并不会发送http请求。比较图片到整个页面距离(Y)和 页面滑动的距离 (X) + 浏览器可视区域的大小(Z) ,Y小于两者之和,则图片就显示出来,将图片的data-set属性换为src属性 Vue的图片懒加载实现 Vue的图片懒加载很简单 (1) 下载插件 npm install vue-lazyload --save 或 yarn add vue-lazyload (2) main.js 引入插件 import Vue from ‘vue’ import VueLazyLoad from ‘vue-lazyload’ Vue.use(VueLazyLoad) 或 Vue.use(VueLazyload, { preLoad: 1.3, // 提前加载高度(数字 1 表示 1 屏的高度) 默认值:1.3 error: ‘dist/error.png’, // 当加载图片失败的时候 loading: ‘dist/loading.gif’, // 图片加载状态下显示的图片 attempt: 3 // 加载错误后最大尝试次数 默认值:3 }) (3)在组件中使用: 对于img v-lazy=“‘/static/img/product/’ + productshow1” // productshow1为路径地址,直接将变量写在data中使用 data: () =>{productshow1:“productshow1.

记一次rsyslog配置问题,导致系统无法打印日志

工作中发现有些机器发生异常,想看下messages日志,却没有数据,看了下rsyslog中日志都定义了打印出的路径,但是就是没有日志 查看结果:所有的日志文件都没有打印数据 查看了下配置文件中都标准的定义了打印的文件路径,但是系统却没有,发现打印的参数被注释了 $IMJournalStateFile imjournal.state #将文件存储在日志中 因此所有的文件都没有存储在对应的日志文件中 [root@k8s-master ~]# cat /etc/rsyslog.conf # rsyslog configuration file # For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html # If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html #### MODULES #### # The imjournal module bellow is now used as a message source instead of imuxsock. $ModLoad imuxsock # provides support for local system logging (e.g. via logger command) #$ModLoad imjournal # provides access to the systemd journal $ModLoad imklog # reads kernel messages (the same are read from journald) #$ModLoad immark # provides --MARK-- message capability # Provides UDP syslog reception #$ModLoad imudp #$UDPServerRun 514 # Provides TCP syslog reception #$ModLoad imtcp #$InputTCPServerRun 514 #### GLOBAL DIRECTIVES #### # Where to place auxiliary files $WorkDirectory /var/lib/rsyslog # Use default timestamp format $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat # File syncing capability is disabled by default.