习题集链接
#include<iostream> using namespace std; int main(){ int a,b,c; cin>>a>>b>>c; cout<<b; return 0; } #include<iostream> using namespace std; int main(){ char c; cin>>c; cout<<" "<<c<endl; cout<<" "<<c<<c<<c<<endl; cout<<c<<c<<c<<c<<c<<endl; cout<<" "<<c<<c<<c<<endl; cout<<" "<<c<<endl; return 0; } #include<iostream> using namespace std; int main(){ char c; cin>>c; cout<<(int)c; return 0; } #include<iostream> using namespace std; int main(){ int c; cin>>c; cout<<(char)c; return 0; } #include<iostream> using namespace std; int main(){ int a; short b; cout<<sizeof(a)<<"
前言 此篇文章基于上一篇HID键盘的开发文章:
蓝牙HID——将android设备变成蓝牙键盘(BluetoothHidDevice)
可先了解上篇文章的内容再来浏览此篇。
开发思路 首先需要建立HID键盘连接,参考上篇。
mBluetoothHidManager = new BluetoothHidManager(this); mBluetoothHidManager.setBluetoothHidStateListener(this); 其次要进行密码设置并保存,这里设置了3种类型的密码:4位数字、6位数字、20位以内密码文本,这些都可以自定义密码类型。
if (checkedId == R.id.rb_four_number) { etPassword.setInputType(EditorInfo.TYPE_CLASS_NUMBER); InputFilter[] filters1 = {new InputFilter.LengthFilter(4)}; etPassword.setFilters(filters1); etPassword.setHint("请输入4位数字"); mPasswordType = TYPE_FOUR_NUMBER; } else if (checkedId == R.id.rb_six_number) { etPassword.setInputType(EditorInfo.TYPE_CLASS_NUMBER); InputFilter[] filters2 = {new InputFilter.LengthFilter(6)}; etPassword.setFilters(filters2); etPassword.setHint("请输入6位数字"); mPasswordType = TYPE_SIX_NUMBER; } else { etPassword.setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD); InputFilter[] filters3 = {new InputFilter.LengthFilter(20)}; etPassword.setFilters(filters3); etPassword.setHint("请输入不大于20位密码"); mPasswordType = TYPE_TEXT; } 接着检查是否设置密码和系统设置解锁密码:
private void checkUnlock() { String password = mPasswordSp.
出现此错误的原因是因为使用了http链接,gradle出于安全考虑必须使用https链接
第一种解决方案是可以加一行参数允许http链接
maven { allowInsecureProtocol = true //这一行 url 'xxxxxxx' } 第二种方法是将url改为https://xxxxxx
常规出现这种问题的原因就这两种,还有一种配置文件会一层一层引用
android/app/build.gradle -> flutter-tools/flutter.gradle -> C:/Users/XXX/.gradle/init.gradle
其中某一个文件的gradle里出现了http,将其用上面两种问题修正即可解决
功能实现:
tabbar导航栏云数据库增删改查 一、效果图: 二、代码 app.json
{ "pages": [ "pages/index/index", "pages/my/my" ], /*** tabbar实现 ***/ "tabBar": { "custom": false, "color": "#7A7E83", "selectedColor": "#3cc51f", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/index/index", "iconPath": "images/index1.png", "selectedIconPath": "images/index2.png", "text": "登录" }, { "pagePath": "pages/my/my", "iconPath": "images/my1.png", "selectedIconPath": "images/my2.png", "text": "我的信息" } ] }, /*** 结束 ***/ "window": { "backgroundColor": "#F6F6F6", "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#F6F6F6", "navigationBarTitleText": "云开发", "navigationBarTextStyle": "black" }, "sitemapLocation": "sitemap.json", "style": "
完整代码
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations") 1、CMAKE_CXX_FLAGS 这种大写的变量,一般都是CMake预定义的内建变量,且他们是全局的。该变量可用于设置编译选项。直接使用set修改其值即可。
除了修改该变量的值之外,还可以通过add_compile_options命令来设置编译选项。它们的区别是:
add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器) CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器 2、$ENV{} $ENV{}用于获取环境变量设置环境变量的方法是:
set(ENV{变量名} 值) 3、CXXFLAGS CXXFLAGS是C++编译器的编译选项。
4、-rdynamic -rdynamic编译选项通知链接器将所有符号添加到动态符号表中。(目的是能够通过使用 dlopen 来实现向后跟踪)
gcc选项-g与-rdynamic的异同
5、-O3 -O3是一个优化选项,告诉编译器优化我们的代码。
gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化
6、-fPIC -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码,即,产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
gcc编译参数-fPIC的一些问题
7、-ggdb -ggdb选项使编译器生成gdb专用的更为丰富的调试信息。
gcc 的 -g 和 -ggdb 选项
8、-std=c++11 -std=c++11设置为使用C++11标准
9、-Wall -Wall选项告诉编译器 编译后显示所有警告。
gcc中的-w -W和-Wall选项
10、-Wno-deprecated 不要警告使用已弃用的功能
11、-Werror 告诉编译器视所有警告为错误,出现任何警告立即放弃编译
12、-Wno-unused-function 关闭 函数被定义了但没有被使用 而产生的警告,即,不使用的函数不警告。
13、-Wno-builtin-macro-redefined 如果某些内置宏被重新定义,请不要警告。这抑制了警告的重新定义__TIMESTAMP__,TIME,DATE,FILE,和__BASE_FILE__。
14、-Wno-deprecated-declarations 关闭使用废弃API的警告。
索引的作用 数据库的索引:为了使得查询数据的效率变快。
数据库索引有哪些 (1)聚集索引(主键索引):在数据库里面,所有的行数都会按照主键索引进行排序。
(2)非聚集索引:给普通的字段加上索引。
(3)联合索引(多属性索引):给好几个字段加上索引。
联合索引的时候怎么走?
key 'idx_age_name_sex' ('age','name','sex') A:select * from student where age = 16 and name = '小张'
B:select * from student where name = '小张' and sex = '男'
C:select * from student where name = '小张' and sex = '男' and age = 18
D:select * from student where age > 20 and name = '小张'
E:select * from student where age != 15 and name = '小张'
git remote show origin ----查看远程仓库的分支
git fetch ----同步远程的分支到本地(本地没有,远程有的同步过来)
git fetch --prune ---(远程删除了,本地没有改变的情况,进行同步)
git fetch +git merge =git pull ----将远程的同步到本地
git branch -a ---查询分支情况
git branch dev ---创建本地分支dev(一般和远程仓库分支同步)
git checkout dev----切换到dev分支上
git checkout master ---切换到主分支上
---本地代码上传远程分支?
1.git clone ......下来远程仓库中的整体代码(包括分支的)
2.在文件夹中右键git bash进入黑窗口,创建本地分支dev(本地分支要和远程分支同名的)---git branch dev
3.然后git pull(相当于刷新远程仓库中代码到本地)
4.git add . (或者git add ‘代码名称’)
5.git commit -m '备注信息' --(做完这一步你就发现你本地那个文件夹中包括你刚复制粘贴进去的你自己的代码文件夹也变绿了)
6.git pull origin 远程分支名(例如git pull origin dev) ---这一步就是合并远程分支名的
7.git push origin 本地分支名:远程分支名(例如:git push origin dev:dev)----这一步就是将代码推送到远程仓库的 如果第一次提交后需要更新代码,继续提交,我们就将代码,再一次放入git中(复制粘贴,替换掉原来的)
问题详情 Stackoverflow:OPTIONS请求跨域问题https://stackoverflow.com/questions/72465838/why-does-this-cors-preflight-did-not-succeed-always-appear-resulting-in-the-use/72470620#72470620
代码参考 if(request.getMethod().equals(RequestMethod.OPTIONS.name())) { response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Headers","*"); response.setHeader("Access-Control-Allow-Methods","*"); response.setHeader("Access-Control-Allow-Credentials","true"); response.setHeader("Access-Control-Max-Age","3600"); response.setStatus(HttpStatus.OK.value()); return true; } 问题解决 之前尝试在拦截器方法内添加此代码块 无效 if(request.getMethod().equals(RequestMethod.OPTIONS.name())) { return true; } 然后发现需要在此代码块内添加跨域Head信息 成功 if(request.getMethod().equals(RequestMethod.OPTIONS.name())) { response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Headers","*"); response.setHeader("Access-Control-Allow-Methods","*"); response.setHeader("Access-Control-Allow-Credentials","true"); response.setHeader("Access-Control-Max-Age","3600"); response.setStatus(HttpStatus.OK.value()); return true; } 报错信息
这是一个系列教程,一是为了解释FLV文件的结构,二是为了练习Go语言,希望大家多多支持。
在实战编码之前,我们需要首先了解FLV文件的格式。FLV是adobe出品的视频封装格式,注意它只是封装格式,不是编码格式。做为第一节的内容,我们不会过度深入音视频数据的编码,这部分内容以后会再讲。
FLV文件格式 FLV文件由FLV Header和FLV Body组成,FLV Body又由许多Tag组成,Tag里面可能是视频、音频或脚本。这里所说的脚本并不是可执行脚本,而是视频的一些元信息。在每一个Tag的前面还有一个重要信息,就是前一个Tag的大小。它们看起来如下图。
为什么Tag之间会记录上一个Tag大小呢?为的是方便回溯,有了前一个Tag大小,我们就可以轻松回溯到前一个Tag了。
FLV Header 1版本的FLV Header共9个字节,目前应该都是这个版本。FLV Header结构如下图。
FLV头的前三个字节分别是FLV三个字母的ASIIC码,可以由此来判断一个文件是否是FLV文件。紧接着的一个字节是FLV文件版本,下一个字节是是一个flag标志,其中第8个比特表示是否包含视频,第6个比特表示是否包含音频,其余比特必须是0,最后是FLV头的大小,占4个字节。
FLV Tag FLV的Tag也由Tag Header和Tag Data组成,Tag Header共计11字节,结构如下图。
FLV Tag有三种类型,它们有相同的Tag Header,不同的是Tag Data中的数据类型。
8:音频Tag,Tag Data中是音频数据。
9:视频Tag,Tag Data中是视频数据。
18:元数据Tag,Tag Data中是视频元信息。
Tag Data大小占3字节,表示Tag Data的长度,不包括Tag Header在内。
关于时间戳,我们要搞清楚以下3个问题:
时间戳的单位是是什么?
时间戳的含义是什么?
时间戳如何计算?
第一个问题,根据官方文档的描述,时间戳的单位是毫秒。
第二个问题,时间戳表示的是相对于第一个Tag时间戳的偏移量,因此第一个Tag的时间戳永远是0。
第三个问题,时间戳在这里被分成了两部分,一个3字节的时间戳和1字节的扩展时间戳,完整的时间戳应该是一个32位无符号整数,计算的时候,扩展时间戳是高8位,时间戳是低24位,在拼时间戳的时候要注意这一点。
流ID实际上源于RTMP协议的多路复用,因为FLV只支持一路流,因此流ID总是0。
基本的FLV结构就介绍到这里,下面开始代码实操。
实战 首先我们需要一个工具提供基础的解码功能,你可以通过导入"gitee.com/lJOSVDE/stream"这个库来使用这个工具。另外我们使用的系统是小端序。
新建一个Go项目以及flv.go文件,首先我们定义两个全局变量。
var ( _FLV_ = [3]byte{'F', 'L', 'V'} FLV_FMT_ERROR = errors.New("flv format error") ) 接下来定义FLV Header和FLV Tag的结构。
// flv头部 type FlvHeader struct { flv [3]byte Version uint8 HasAudio bool HasVideo bool Size uint32 } // flv tag type FlvTag struct { Header FlvTagHeader Data stream.
前言:总纲请查看《计算机视觉学习路》
环境配置: 新建requirements.txt,保存以下内容,然后执行命令创建虚拟环境
conda create --name py39-opencv --file requirements.txt
然后就可以在pycharm配置该环境进行编译
# This file may be used to create an environment using: # $ conda create --name <env> --file <this file> # platform: linux-64 _libgcc_mutex=0.1=conda_forge _openmp_mutex=4.5=2_gnu bzip2=1.0.8=h7f98852_4 ca-certificates=2022.5.18.1=ha878542_0 cvzone=1.5.6=pypi_0 cycler=0.11.0=pypi_0 evdev=1.5.0=pypi_0 fonttools=4.33.3=pypi_0 kiwisolver=1.4.2=pypi_0 ld_impl_linux-64=2.36.1=hea4e1c9_2 libffi=3.4.2=h7f98852_5 libgcc-ng=12.1.0=h8d9b700_16 libgomp=12.1.0=h8d9b700_16 libnsl=2.0.0=h7f98852_0 libuuid=2.32.1=h7f98852_1000 libzlib=1.2.11=h166bdaf_1014 matplotlib=3.5.2=pypi_0 ncurses=6.3=h27087fc_1 numpy=1.22.4=pypi_0 opencv-python=4.5.5.64=pypi_0 openssl=3.0.3=h166bdaf_0 packaging=21.3=pypi_0 pillow=9.1.1=pypi_0 pip=22.1.1=pyhd8ed1ab_0 pynput=1.7.6=pypi_0 pyparsing=3.0.9=pypi_0 python=3.9.12=h2660328_1_cpython python-dateutil=2.8.2=pypi_0 python-xlib=0.31=pypi_0 python_abi=3.9=2_cp39 readline=8.1=h46c0cb4_0 setuptools=62.3.2=py39hf3d152e_0 six=1.16.0=pypi_0 sqlite=3.38.5=h4ff8645_0 tk=8.6.12=h27826a3_0 tzdata=2022a=h191b570_0 wheel=0.
如果涉及到表的schema改变,使用invalidate metadata [table_name]
如果只是涉及到表的数据改变,使用refresh [table_name]
如果只是涉及到表的某一个分区数据改变,使用refresh [table_name] partition [partition]
impala-shell -i node_name -q ‘refresh table_name;’
hive客户端显示数据库,查询显示列名称
一次配置,永久生效,在当前用户的HOME目录下,新建.hiverc文件,把属性设置命令放置到该文件中,每次打开cli时,都会先执行该文件。
– 打印表头
set hive.cli.print.header=true;
set hive.cli.print.row.to.vertical=true;
set hive.cli.print.row.to.vertical.num=1;
– 显示当前数据库
set hive.cli.print.current.db=true;
hive的几种格式:
数据仓库的开发是逐步完善的原型法的开发方法,它要求:要尽快地让系统运行起来,尽早产生效益;要在系统运行或使用中,不断地理解需求,改善系统;不断地考虑新的需求,完善系统。
维护数据仓库的工作主要是管理日常数据装入的工作,包括刷新数据仓库的当前详细数据,将过时的数据转化成历史数据.清除不再使用的数据,管理元数据,等等;另外,如何利用接口定期从操作型环境向数据仓库追加数据,确定数据仓库的数据刷新频率,等等。
建模
1、介绍
Hive作为数据仓库,同关系型数据库开发过程类似,都需要先进行建模,所谓建模,就是对表之间指定关系方式。建模在hive中大致分为星型、雪花型和星座型。要对建模深入理解,首先需要对hive数仓中的集中表概念进行界定。hive中的表从形态上分内部表、外部表、桶表、分区表。在数据逻辑上划分为维度表和事实表。维度表等价于我们常说的字典表。事实表就是字典表之外的数据表。
1.1 星型
多张维度表,一张事实表,维度表之间没有关系。查询性能要好些,存储有冗余的。星型模型使用的比较多。
1.2 雪花型
雪花型是星型建模的扩展,维度表之间有关系。存储减少冗余,查询性能有损失,需要多级连接。和星型模型的共性就是只有一张是事实表。
1.3 星座型
星座型也是星型模型的扩展,存在多张事实表。
数据仓库分层:
ODS层:原始同步数据(或者清洗后的数据)
DW层:数据汇总层,宽表
DM层:数据集市层(各种维度表)
应用层:从集市层拿出需要的数据同步到数据库(Mongodb/Oracle)
事实表是数据仓库结构中的中央表,它包含联系事实与维度表的数字度量值和键。事实数据表包含描述业务(例如产品销售)内特定事件的数据。
维度表是维度属性的集合。是分析问题的一个窗口。是人们观察数据的特定角度,是考虑问题时的一类属性,属性的集合构成一个维。数据库结构中的星型结构,该结构在位于结构中心的单个事实数据表中维护数据,其它维度数据存储在维度表中。每个维度表与事实数据表直接相关,且通常通过一个键联接到事实数据表中。星型架构是数据仓库比较流向的一种架构。
1)、事实表就是你要关注的内容;
2)、维度表就是你观察该事务的角度,是从哪个角度去观察这个内容的。
例如,某地区商品的销量,是从地区这个角度观察商品销量的。事实表就是销量表,维度表就是地区表
4、主题表:主题(Subject)是在较高层次上将企业信息系统中的数据进行综合、归类和分析利用的一个抽象概念,每一个主题基本对应一个宏观的分析领域。在逻辑意义上,它是对应企业中某一宏观分析领域所涉及的分析对象。例如“销售分析”就是一个分析领域,因此这个数据仓库应用的主题就是“销售分析”。
面向主题的数据组织方式,就是在较高层次上对分析对象数据的一个完整并且一致的描述,能刻画各个分析对象所涉及的企业各项数据,以及数据之间的联系。所谓较高层次是相对面向应用的数据组织方式而言的,是指按照主题进行数据组织的方式具有更高的数据抽象级别。与传统数据库面向应用进行数据组织的特点相对应,数据仓库中的数据是面向主题进行组织的。例如,一个生产企业的数据仓库所组织的主题可能有产品订货分析和货物发运分析等。而按应用来组织则可能为财务子系统、销售子系统、供应子系统、人力资源子系统和生产调度子系统。
5、汇总数据层:聚合原子粒度事实表及维度表,为满足固定分析需求,以提高查询性能为目的,形成的高粒度表,如周报、月报、季报、年报等。
6、应用层:
为应用层,这层数据是完全为了满足具体的分析需求而构建的数据,也是星形结构的数据。应用层为前端应用的展现提现数据,可以为关系型数据库组成
hive优化
1、设置合理的map reduce的task数量 可以使用默认的
map阶段优化
mapred.min.split.size: 指的是数据的最小分割单元大小;min的默认值是1B
mapred.max.split.size: 指的是数据的最大分割单元大小;max的默认值是256MB
通过调整max可以起到调整map数的作用,减小max可以增加map数,增大max可以减少map数。
cpu架构:x86操作系统:ubuntu18.04 受够了TensorRT+cuda+opencv+ffmpeg+x264运行环境的部署的繁琐,每次新服务器上部署环境都会花费很大的精力去部署环境,听说nvidia-docker可以省去部署的麻烦,好多人也推荐使用docker方便部署,咱也在网上搜索了下,学习了下,根据网上的资料,开始安装docker学习一下,把学习记录记在这儿,听说要想使用GPU,就要安装Docker-CE和NVIDIA Container Toolkit,好的,开始。
1.安装Dokcer-CE 首先,我的机器上没有安装过docker,要先把docker安装上,执行以下脚本,开始安装。
curl https://get.docker.com | sh \ > && sudo systemctl --now enable docker 控制台输出结果如下:
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 19325 100 19325 0 0 2210 0 0:00:08 0:00:08 --:--:-- 4718 # Executing docker install script, commit: 3255aa3919e7281693f62855b9d543bb50f04957 + sudo -E sh -c apt-get update -qq >/dev/null [sudo] dingxin 的密码: + sudo -E sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null + sudo -E sh -c mkdir -p /etc/apt/keyrings && chmod -R 0755 /etc/apt/keyrings + sudo -E sh -c curl -fsSL "
1、Manifest文件修改MainActivity属性
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <data android:host="@string/app_name" android:scheme="com.xxx.xxx.mainActivity" tools:ignore="AppLinkUrlError,ManifestResource"/> </intent-filter> </activity> 2、修改MainActivity
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); moveTaskToBack(isFinishing()); finish(); } @Override protected void onResume() { moveTaskToBack(isFinishing()); super.onResume(); } @Override protected void onNewIntent(Intent intent) { moveTaskToBack(isFinishing()); super.onNewIntent(intent); finish(); }
什么是负载均衡
产品架构
应用场景
一、什么是负载均衡
负载均衡(Server Load Balancer)是将访问流量根据转发策略分发到后端多台云服务器(ECS实例)的流量分发控制服务。负载均衡扩展了应用的服务能力,增强了应用的可用性。
概述 负载均衡通过设置虚拟服务地址,将添加的同一地域的多台ECS实例虚拟成一个高性能、高可用的后端服务池,并根据转发规则,将来自客户端的请求分发给后端服务器池中的ECS实例。
负载均衡默认检查云服务器池中的ECS实例的健康状态,自动隔离异常状态的ECS实例,消除了单台ECS实例的单点故障,提高了应用的整体服务能力。此外,负载均衡还具备抗DDoS攻击的能力,增强了应用服务的防护能力。
组成部分 负载均衡由以下三个部分组成:
负载均衡实例 (Server Load Balancer instances)一个负载均衡实例是一个运行的负载均衡服务,用来接收流量并将其分配给后端服务器。要使用负载均衡服务,您必须创建一个负载均衡实例,并至少添加一个监听和两台ECS实例。监听 (Listeners)监听用来检查客户端请求并将请求转发给后端服务器。监听也会对后端服务器进行健康检查。后端服务器(Backend Servers)一组接收前端请求的ECS实例。您可以单独添加ECS实例到后端服务器池,也可以通过虚拟服务器组或主备服务器组来批量添加和管理。 产品优势 高可用采用全冗余设计,无单点,支持同城容灾。搭配DNS可实现跨地域容灾,可用性高达99.95%。根据应用负载进行弹性扩容,在流量波动情况下不中断对外服务。可扩展您可以根据业务的需要,随时增加或减少后端服务器的数量,扩展应用的服务能力。低成本与传统硬件负载均衡系统高投入相比,成本可下降60%。安全结合云盾,可提供5Gbps的防DDoS攻击能力。高并发集群支持亿级并发连接,单实例提供千万级并发能力。 二、产品架构
负载均衡基础架构是采用集群部署,提供四层(TCP协议和UDP协议)和七层(HTTP和HTTPS协议)的负载均衡,可实现会话同步,以消除服务器单点故障,提升冗余,保证服务的稳定性。
负载均衡作为流量转发服务,将来自客户端的请求通过负载均衡集群转发至后端服务器,后端服务器再将响应通过内网返回给负载均衡。
基础架构说明 阿里云当前提供四层和七层的负载均衡服务。
四层采用开源软件LVS(Linux Virtual Server)+ keepalived的方式实现负载均衡,并根据云计算需求对其进行了个性化定制。七层采用Tengine实现负载均衡。Tengine是由淘宝网发起的Web服务器项目,它在Nginx的基础上,针对有大访问量的网站需求,添加了很多高级功能和特性。 如下图所示,各个地域的四层负载均衡实际上是由多台LVS机器部署成一个LVS集群来运行的。采用集群部署模式极大地保证了异常情况下负载均衡服务的可用性、稳定性与可扩展性。
LVS集群内的每台LVS都会进行会话,通过组播报文同步到该集群内的其它LVS机器上,从而实现LVS集群内各台机器间的会话同步。如下图所示,当客户端向服务端传输三个数据包后,在LVS1上建立的会话A开始同步到其它LVS机器上。图中实线表示现有的连接,图中虚线表示当LVS1出现故障或进行维护时,这部分流量会走到一台可以正常运行的机器LVS2上。因而负载均衡集群支持热升级,并且在机器故障和集群维护时最大程度对用户透明,不影响用户业务。
入网流量路径 对于入网流量,负载均衡会根据用户在控制台或API上配置的转发策略,对来自前端的访问请求进行转发和处理,数据流转如下图所示。
图 1. 入网流量路径
TCP/UDP协议和HTTP/HTTPS协议的流量都需要经过LVS集群进行转发。LVS集群内的每一台节点服务器均匀地分配海量访问请求,并且每一台节点服务器之间都有会话同步策略,以保证高可用。如果相应的负载均衡实例服务端口使用的是四层协议(TCP或UDP),那么LVS集群内每个节点都会根据负载均衡实例负载均衡策略,将其承载的服务请求按策略直接分发到后端ECS服务器。如果相应的负载均衡实例服务端口使用的是七层HTTP协议,那么LVS集群内每个节点会先将其承载的服务请求均分到Tengine集群,Tengine集群内的每个节点再根据负载均衡策略,将服务请求按策略最终分发到后端ECS服务器。如果相应的负载均衡实例服务端口使用的是七层HTTPS协议,与上述HTTP处理过程类似,差别是在按策略将服务请求最终分发到后端ECS服务器前,先调用Key Server进行证书验证及数据包加解密等前置操作。 出网流量路径 负载均衡SLB和后端ECS之间是通过内网进行通信的。
如果ECS仅仅处理来自负载均衡的请求,可以不购买公网带宽(ECS公网IP/弹性公网IP/NAT网关等)。如果需要直接通过后端ECS对外提供服务,或后端ECS有访问外网的需求, 那么需要相应的配置或购买ECS公网IP/弹性公网IP/NAT网关等服务。ECS的公网流量访问路径如下图所示。图 2. 出网流量路径 总体原则:流量从哪里进来,就从哪里出去。
通过负载均衡进入的流量在负载均衡SLB上限速/计费,仅收取出方向流量费用,入方向流量不收取(在未来可能会改变),SLB到ECS之间是阿里云内网通信,不收取流量费用。来自弹性公网IP/NAT网关的流量,分别在弹性公网IP/NAT网关上进行限速/计费,如果在购买ECS时选择了公网带宽,限速/计费点在ECS上。负载均衡SLB仅提供被动访问公网的能力,即后端ECS只能在收到通过负载均衡SLB转发来的公网的请求时,才能访问公网回应该请求,如后端ECS希望主动发起公网访问,则需要配置/购买ECS公网带宽、弹性公网IP或NAT网关来实现。ECS公网带宽(购买ECS时配置)、弹性公网IP、NAT网关均可以实现ECS的双向公网访问(访问或被访问),但没有流量分发和负载均衡的能力。 三、应用场景
负载均衡的应用场景为高访问量的业务,提高应用程序的可用性和可靠性。
应用于高访问量的业务 如果您的应用访问量很高,您可以通过配置监听规则将流量分发到不同的ECS实例上。此外,您可以使用会话保持功能将同一客户端的请求转发到同一台后端ECS,提高访问效率。
扩展应用程序 您可以根据业务发展的需要,随时添加和移除ECS实例来扩展应用系统的服务能力,适用于各种Web服务器和App服务器。
消除单点故障 您可以在负载均衡实例下添加多台ECS实例。当其中一部分ECS实例发生故障后,负载均衡会自动屏蔽故障的ECS实例,将请求分发给正常运行的ECS实例,保证应用系统仍能正常工作。
同城容灾 (多可用区容灾) 为了提供更加稳定可靠的负载均衡服务,阿里云负载均衡已在各地域部署了多可用区以实现同地域容灾。当主可用区出现机房故障或不可用时,负载均衡仍然有能力在非常短的时间内(大约30s中断)切换到另外一个备可用区恢复服务能力;当主可用区恢复时,负载均衡同样会自动切换到主可用区提供服务。
使用负载均衡时,您可以将负载均衡实例部署在支持多可用区的地域以实现同城容灾。此外,建议您结合自身的应用需要,综合考虑后端服务器的部署。如果您的每个可用区均至少添加了一台ECS实例,那么此种部署模式下的负载均衡服务的效率是最高的。
如下图所示,在负载均衡实例下绑定不同可用区的ECS实例。正常情况下,用户访问流量将同时转发至主、备可用区内的ECS实例;当可用区A发生故障时,用户访问流量将只转发至备可用区内的ECS实例。此种部署既可以避免因为单个可用区的故障而导致对外服务的不可用,也可以通过不同产品间可用区的选择来降低延迟。
如果您采取如下图所示的部署方案,即在负载均衡实例的主可用区下绑定多台ECS实例,而在备可用区没有任何ECS实例。当主可用区发生故障时会造成业务中断,因为备可用区没有ECS实例来接收请求。这样的部署方式很明显是以牺牲高可用性为代价来获取低延时。
跨地域容灾 您可以在不同地域下部署负载均衡实例,并分别挂载相应地域内不同可用区的ECS。上层利用云解析做智能DNS,将域名解析到不同地域的负载均衡实例服务地址下,可实现全局负载均衡。当某个地域出现不可用时,暂停对应解析即可实现所有用户访问不受影响。
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见!学习更多JAVA知识与技巧,关注与私信博主(666)
目录 一.部署zabbix安装zabbix-server替换阿里云Zabbix源安装Zabbix server 和 agent安装Zabbix frontend安装 Zabbix frontend packages安装Mysql数据库创建初始数据库为Zabbix server配置数据库为Zabbix前端配置PHP启动Zabbix server和agent进程 二.监控vcenter修改配置文件创建Vcenter主机链接Template VM VMware模板定义宏信息 结果展示 一.部署zabbix 安装zabbix-server 首先在虚拟机上把Centos7安装完毕并关闭防火墙与SElinux。
打开Zabbix官网选择Zabbix版本-OS系统-OS版本-数据库-WebServer
替换阿里云Zabbix源 编写shell脚本zabbix_aliyun.s
#!/bin/bash echo -e "请给出要安装的zabbix版本号,建议使用4.x的版本 \033[31musage:./zabbix_aliyun.sh 4.0|4.4|4.5|5.0 \033[0m" echo "例如要安装4.4版本,在命令行写上 ./zabbix_aliyun.sh 4.4" if [ -z $1 ];then exit fi VERSION=$1 if [ -f /etc/yum.repos.d/zabbix.repo ];then rm -rf /etc/repos.d/zabbix.repo fi rpm -qa | grep zabbix-release && rpm -e zabbix-release rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/$VERSION/rhel/7/x86_64/zabbix-release-$VERSION-1.el7.noarch.rpm sed -i "s@zabbix/.*/rhel@zabbix/$VERSION/rhel@g" /etc/yum.repos.d/zabbix.repo sed -i 's@repo.zabbix.com@mirrors.aliyun.com/zabbix@g' /etc/yum.repos.d/zabbix.repo [ $?
下载地址
口红西瓜HTML5见缝插针手机游戏代码,口红西瓜见缝插针手机游戏源代码。
dd:
一、复制算法 在上面提到的标记清除算法中,遇到了一个典型的问题,那就是内存碎片的问题。整理内存碎片是一个漫长的不断的搜索的过程。那么有没有一种算法可以解决这个问题呢?这就引出了GC复制算法。这种算法是把整个空间分成From和To相等的两部分,当From部分达到GC阈值时,就将From部分活动内存对象全部复制到To部分。复制完成后,From和To的身份互换。
这个想法有点奇特,不过却挺管用。很明显,这个全拷贝需要一个递归的搜索函数。当然这个问题可以用迭代来搞定。
二、优缺点 GC复制算法的优点:
1、首先就解决了内存碎片问题
把内存都全拷贝走了,还有啥碎片问题,一个新世界都诞生了,哪里还有什么内存的问题。
2、吞吐量高
标记删除算法中,不断标记的过程比较麻烦,不断的遍历,而复制算法就不用,只在GC时搜索一次活动对象,那速度肯定快,吞吐量自然大。特别是内存很大的情况,更有优势。
3、分配效率高
这个是上面一个意思,不需要寻找空闲链表了,直接就开始分配,你说快不快。
4、对缓存的良好性
现代的缓存手段,导致内存在分配上有一定的方式,保障能快速命中,而这种复制算法对其就表现了良好的支持。
GC复制算法的缺点“
1、消耗内存
这种二分法空间,意味着一半的内存永远是空闲状态,也就是现在内存便宜了,要搁以前,估计会被打死。
2、对保守式GC不兼容
这个其实倒不算啥,但多一个朋友多一条出路,所以这也算一个缺点。
三、基本应用 Cheney的GC复制算法算是一个比较好的GC复制算法。而且它不采用递归算法来进行GC,而是采用迭代的方式。递归的缺点,凡是学过算法和数据结构的估计都明白,不容易调试,容易栈溢出等等。同时它也通过堆队列的方式缩小了遍历的代价,不过缺点是,对缓存不再有良好的支持。
GC复制算法一般有以下几步:
1、二分划分内存,指定From和To空间
2、开始GC,复制内存对象从From到To空间
3、复制完成后,修改根指针对象,这个很重要
4、回收From空间内存对象并交换From和To空间
这里面其实有一个小细节需要考虑,在真实的应用场景中,一个对象可能会被多个对象引用,那么在复制时,要考虑不能将它复制多份儿。至于是使用标记还是使用其它方式,就看开发者的想法了。
四、总结 哲学上有辩证统一这个观点,用在GC的算法分析上,其实是相通的。而在实际社会上也是如此,康熙说过:”凡生一事,有一利而必有一弊“。GC算法没有一种能包打天下,一定要弄明白这个道理。做为一名程序员一定要知道,最合适的才是最好的。也正如NP问题,只有最接近的,没有能完全解决的。
背景:ubuntu20.04上安装klee2.2
官网安装教程:KLEE2-2安装教程(不是很详细,仅参考)
本文的安装环境全部放在/opt/klee_env下,root用户下执行命令
1.安装必备工具和依赖 sudo apt-get install build-essential curl libcap-dev git cmake libncurses5-dev python-minimal python-pip unzip libtcmalloc-minimal4 libgoogle-perftools-dev libsqlite3-dev doxygen sudo apt-get install python3 python3-pip gcc-multilib g++-multilib sudo pip3 install lit tabulate wllvm sudo apt-get install zlib1g-dev 2.安装LLVM9 对于版本在18.04以上的Ubuntu,可以直接使用包管理器安装LLVM套件 sudo apt-get install clang-9 llvm-9 llvm-9-dev llvm-9-tools 3.安装约束求解器z3(时间有点长) git clone https://github.com/Z3Prover/z3.git cd z3/ python scripts/mk_make.py sudo make install 4.安装uClibc 和 POSIX 环境(建议安装) 如果想使用 KLEE 来运行实际程序,将需要启用 KLEE POSIX 运行时,它构建在uClibc C 库之上。毕竟针对实际程序还是有用的
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
最近在做MySQL适配postgreSql数据库,因MySQL表字段名均为驼峰,且psql语句不识别驼峰字段,适配方案原本有两种:
A、不改表结构,只改实现层
B、更改表结构,并改实现层
最终采取了B方案,只是因为驼峰命名实在太坑了 -_- ,mybatis_puls的查询构造和条件构造均不能为驼峰字段的首尾拼接双引号,导致使用mybatis_puls的增删改查均报错,最终的解决方案只能是修改mybatis的源码,遂放弃。
记录修改表字段的代码:
@Transactional(rollbackFor = {Exception.class, Error.class}) public void test(){ //获取所有表名 List<String> tableNames = baseMapper.getTableNameList(); //循环更改每张表字段 tableNames.forEach(t -> { StringBuilder sql = new StringBuilder(); //获取所有字段名 List<String> columns = baseMapper.getColumnNameList(t); //将驼峰转为蛇形 columns.forEach(c -> { List<String> oldAndNew = toSerpentine(c); Optional.ofNullable(oldAndNew).ifPresent(f -> { //需转换的字段 StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(" ALTER TABLE public.") .append(t) .append(" RENAME COLUMN ") .append(oldAndNew.get(0)) .append(" to ") .append(oldAndNew.get(1)) .append(" ;"); sql.append(stringBuilder); }); }); System.
CMMI资质认证想必已经有不少企业已经了解过了,很多企业只了解到CMMI的基础知识,却不明白CMMI也有不同的版本,CMMI1.3版本自动20年10月更改为2.0版本,那CMMI的一个版本升级都有哪些区别呢?今天同邦信息科技的小编就给大家说一下
CMMI V2.0是一个动态的模型,可以快速扩展以接入新的方法论和实践,V2.0关注更有意义的结果并将改善方法与组织的业务目标相结合,它为组织带来的价值远远超出了评估和成熟度等级本身。
CMMI V2.0与CMMIV1.3的术语区别 1、“过程域”调整为“实践域”。
强调了CMMIV2.0是一系列最佳实践的集合而不是待实施的过程的集合。
2、增加内核内容(Core)和场景内容(ContextSpecific)。
每个实践域都分解为一个共通描述章节(内核信息)以及可适用的场景描述章节(特定场景)。
3、“必需的/期望的/说明性的”调整为“必需的/说明性的”
必需的内容是获得评估等级的必要条件。注意:模型中将没有“期望的”内容,所有实践都是必需的。
4、共性实践和共性目标由两个制度化实践域代替,即治理和落实基础设施
以避免重复同时强调制度化的含义。没有了共性实践,也不需要特定实践与之对应。
5、“采购”调整为“供应商管理”。
CMMI V2.0与CMMIV1.3评估方法区别 CMMI2.0正式版评估将采用四种评估方式,以减少评估成本以及组织过往对于评估之后缺乏类似ISO9001的监督评审的弊端。
四种新的评估方式分别为:基准评估、维持评估、改善计划再评估、评价评估。
1、基准评估提供正式的评估,有效期3年;
2、维持评估借鉴9001的监督评估,在组织通过基准评估后没有大的组织架构的变动下,提供2年有效期,并减少30%的评估成本;
3、 改善计划再评估针对第一次基准评估中失败的组织再一次通过评估的机会;
4、 评价评估则为组织在评估前进行一次非正式的评估以衡量组织是否达到了CMMI2.0的实践要求。
综上所述就是CMMI2.0和1.3评估方法的一个本质区别,同邦信息科技的小编就先给大家说到这里了,两者之间还有很多的区别,可以关注我们了解更多哟,关于CMMI有什么不懂得问题可以来咨询我们的顾问老师哟!