首页 文章 精选 留言 我的

精选列表

搜索[搭建],共10007篇文章
优秀的个人博客,低调大师

RocketMQ双Master集群搭建

机器准备 2台独立的linux主机, 内网IP分别为: 172.31.175.142/143 172.31.175.142 NameServer1、 Broker Master1 172.31.175.143 NameServer2、 Broker Master2 安装配置 安装 下载二进制版本解压即可 wget http://mirrors.hust.edu.cn/apache/rocketmq/4.3.0/rocketmq-all-4.3.0-bin-release.zip unzip rocketmq-all-4.3.0-bin-release.zip -d ~ cd ~ mv rocketmq-all-4.3.0-bin-release rocketmq 启动NameServer 命令的std输出使用默认的运行日志 mkdir -p ~/logs/rocketmqlogs nohup sh bin/mqnamesrv >~/logs/rocketmqlogs/namesrv.log 2>&1 & tail -100f ~/logs/rocketmqlogs/namesrv.log 配置/启动Broker 1) master1 进入172.31.175.142,编辑预制的配置文件conf/2m-noslave/broker-a.properties, 追加namesrv地址 namesrvAddr=172.31.175.142:9876;172.31.175.143:9876 brokerClusterName=DefaultCluster brokerName=broker-a brokerId=0 deleteWhen=04 fileReservedTime=48 brokerRole=ASYNC_MASTER flushDiskType=ASYNC_FLUSH 启动broker, 指定配置文件broker-a.properties nohup sh bin/mqbroker -c ~/rocketmq/conf/2m-noslave/broker-a.properties >~/logs/rocketmqlogs/broker.log 2>&1 & tail -100f ~/logs/rocketmqlogs/broker.log 2) master2 进入172.31.175.143,编辑预制的配置文件conf/2m-noslave/broker-b.properties, 追加namesrv地址 namesrvAddr=172.31.175.142:9876;172.31.175.143:9876 brokerClusterName=DefaultCluster brokerName=broker-b brokerId=0 deleteWhen=04 fileReservedTime=48 brokerRole=ASYNC_MASTER flushDiskType=ASYNC_FLUSH 启动broker, 指定配置文件broker-b.properties nohup sh bin/mqbroker -c ~/rocketmq/conf/2m-noslave/broker-b.properties >~/logs/rocketmqlogs/broker.log 2>&1 & tail -100f ~/logs/rocketmqlogs/broker.log 查看集群状态 sh bin/mqadmin clusterlist -n 172.31.175.142:9876;172.31.175.143:9876 双master集群信息如下 #Cluster Name #Broker Name #BID #Addr #Version #InTPS(LOAD) #OutTPS(LOAD) #PCWait(ms) #Hour #SPACE DefaultCluster broker-a 0 172.31.175.142:10911 V4_3_0 0.00(0,0ms) 0.00(0,0ms) 0 427546.59 -1.0000 DefaultCluster broker-b 0 172.31.175.143:10911 V4_3_0 0.00(0,0ms) 0.00(0,0ms) 0 427546.59 -1.0000

优秀的个人博客,低调大师

kubernetes搭建mysql集群服务

参考链接:https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/ 一、创建ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: mysql labels: app: mysql data: master.cnf: | # Apply this config only on the master. [mysqld] log-bin slave.cnf: | # Apply this config only on slaves. [mysqld] super-read-only 在pod初始化时, pod会根据自身标识(master或slave)从configmap中应用指定配置. 被应用配置将覆盖my.cnf中的配置. 目的是使master向slave提供复制日志服务,并设置slave拒绝非复制写入. 二、创建headless service # Headless service for stable DNS entries of StatefulSet members. apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - name: mysql port: 3306 clusterIP: None selector: app: mysql 三、创建StatefulSet apiVersion: apps/v1beta1 apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql spec: selector: matchLabels: app: mysql serviceName: mysql replicas: 3 template: metadata: labels: app: mysql spec: initContainers: - name: init-mysql image: mysql:5.7 command: - bash - "-c" - | set -ex # Generate mysql server-id from pod ordinal index. [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} echo [mysqld] > /mnt/conf.d/server-id.cnf # Add an offset to avoid reserved server-id=0 value. echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf # Copy appropriate conf.d files from config-map to emptyDir. if [[ $ordinal -eq 0 ]]; then cp /mnt/config-map/master.cnf /mnt/conf.d/ else cp /mnt/config-map/slave.cnf /mnt/conf.d/ fi volumeMounts: - name: conf mountPath: /mnt/conf.d - name: config-map mountPath: /mnt/config-map - name: clone-mysql image: gcr.io/google-samples/xtrabackup:1.0 command: - bash - "-c" - | set -ex # Skip the clone if data already exists. [[ -d /var/lib/mysql/mysql ]] && exit 0 # Skip the clone on master (ordinal index 0). [[ `hostname` =~ -([0-9]+)$ ]] || exit 1 ordinal=${BASH_REMATCH[1]} [[ $ordinal -eq 0 ]] && exit 0 # Clone data from previous peer. ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql # Prepare the backup. xtrabackup --prepare --target-dir=/var/lib/mysql volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: "123", - name: MYSQL_REPLICATION_USER value: "sync", - name: MYSQL_REPLICATION_PASSWORD value: "sync", ports: - name: mysql containerPort: 3306 volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d resources: requests: cpu: 500m memory: 1Gi livenessProbe: exec: command: ["mysqladmin", "-uroot", "-p123", "ping"] initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 readinessProbe: exec: # Check we can execute queries over TCP (skip-networking is off). command: ["mysql", "-h", "127.0.0.1", "-uroot", "-p123", "-e", "SELECT 1"] initialDelaySeconds: 5 periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup image: gcr.io/google-samples/xtrabackup:1.0 ports: - name: xtrabackup containerPort: 3307 command: - bash - "-c" - | set -ex cd /var/lib/mysql # Determine binlog position of cloned data, if any. if [[ -f xtrabackup_slave_info ]]; then # XtraBackup already generated a partial "CHANGE MASTER TO" query # because we're cloning from an existing slave. mv xtrabackup_slave_info change_master_to.sql.in # Ignore xtrabackup_binlog_info in this case (it's useless). rm -f xtrabackup_binlog_info elif [[ -f xtrabackup_binlog_info ]]; then # We're cloning directly from master. Parse binlog position. [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 rm xtrabackup_binlog_info echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\ MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in fi # Check if we need to complete a clone by starting replication. if [[ -f change_master_to.sql.in ]]; then echo "Waiting for mysqld to be ready (accepting connections)" until mysql -h 127.0.0.1 -uroot -p123 -e "SELECT 1"; do sleep 1; done echo "Initializing replication from clone position" # In case of container restart, attempt this at-most-once. mv change_master_to.sql.in change_master_to.sql.orig mysql -h 127.0.0.1 -uroot -p123 <<EOF $(<change_master_to.sql.orig), MASTER_HOST='mysql-0.mysql', MASTER_USER='root', MASTER_PASSWORD='123', MASTER_CONNECT_RETRY=10; START SLAVE; EOF fi # Start a server to send backups when requested by peers. exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \ "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root --password=123" volumeMounts: - name: data mountPath: /var/lib/mysql subPath: mysql - name: conf mountPath: /etc/mysql/conf.d resources: requests: cpu: 100m memory: 100Mi volumes: - name: conf emptyDir: {} - name: config-map configMap: name: mysql volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi 这里使用了两个初始化容器. 第一个初始化容器init-mysql作用包括根据pod名称后缀生成server_id文件, 从configmap中获取指定配置. 这里默认StatefulSet控制的第一个pod即mysql-0为master, 其余为slave. 第二个clone-mysql使用开源工具xtrabackup, 用于当前slave从前一个slave复制数据, 当有新的作为slave的pod加入集群时, 这个pod会从上一个pod(序号小1)的非master的pod复制数据, 因为新pod加入时, 我们必须假定master中的数据是不为空的, 需要进行一次复制操作, 这样在扩容时会避免数据丢失,而从前一个pod复制数据是因为StatefulSet按顺序启动, 当前一个pod为ready时才启动后一个pod的机制而来. 当init容器执行完成后, 常规容器开始启动并运行. mysql Pods由运行mysqld服务的mysql容器和充当SideCar的xtrabackup容器组成(挎斗模式解析请见http://www.mamicode.com/info-detail-2149700.html)。 四、创建用于访问Service # Client service for connecting to any MySQL instance for reads. # For writes, you must instead connect to the master: mysql-0.mysql. apiVersion: v1 kind: Service metadata: name: mysql-access labels: app: mysql spec: ports: - name: mysql port: 3306 selector: app: mysql 五、查看 root@node4:~# kubectl -n admin-d2069c get pvc,pv,statefulset,pod,service,configmap |grep mysql pvc/storage-mysql-0 Bound pvc-bb591208-c2f4-11e8-b599-0050568eef9f 512M RWX managed-nfs-storage 12m pvc/storage-mysql-1 Bound pvc-c4ada169-c2f4-11e8-b599-0050568eef9f 512M RWX managed-nfs-storage 12m pvc/storage-mysql-2 Bound pvc-ce20ad71-c2f4-11e8-b599-0050568eef9f 512M RWX managed-nfs-storage 11m pv/pvc-bb591208-c2f4-11e8-b599-0050568eef9f 512M RWX Delete Bound admin-d2069c/storage-mysql-0 managed-nfs-storage 12m pv/pvc-c4ada169-c2f4-11e8-b599-0050568eef9f 512M RWX Delete Bound admin-d2069c/storage-mysql-1 managed-nfs-storage 12m pv/pvc-ce20ad71-c2f4-11e8-b599-0050568eef9f 512M RWX Delete Bound admin-d2069c/storage-mysql-2 managed-nfs-storage 11m statefulsets/mysql 3 3 12m po/mysql-0 2/2 Running 0 12m po/mysql-1 2/2 Running 0 12m po/mysql-2 2/2 Running 0 11m svc/mysql ClusterIP None <none> 3306/TCP 12m svc/mysql-access ClusterIP 10.68.8.223 <none> 3306/TCP 12m cm/mysql 2 12m 六、测试集群 登录mysql-0, 执行 kubectl -n admin-d2069c exec -it mysql-0 /bin/bash 进入mysql-0后连接mysql: mysql -p123 创建database, 并以同样方式登录mysql-1或mysql-2, 发现其下已经将新创建的database同步则为验证成功.

优秀的个人博客,低调大师

Django搭建个人博客(一)

什么是 Django Django 是一个基于 python 的高级 web 开发框架。 它能够让开发人员进行高效且快速的开发。 高度集成(不用自己造轮子),免费并且开源。我们只要专注于网站本身的开发就好了。 浏览器浏览网页的基本原理 本质是网络通信,即通过网络进行数据传输 浏览器经过通信后获取到该页面的源代码文档(HTML等) 浏览器解析文档后以适当的形式展现给用户 创建项目 在 pycharm 中新建 Django 项目。 项目目录结构: 目录结构 manage.py 文件 它是与项目进行交互的命令行工具集的入口 也就是项目管理器 我们点运行命令: 运行 下方控制台输出: Performing system checks... System check identified no issues (0 silenced). You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. September 28, 2018 - 12:14:15 Django version 2.0.6, using settings 'myblog.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. 项目开始运行在我们本地,打开网址:http://127.0.0.1:8000 。就可以看到我们的项目已经开启了。 项目开启 myblog 目录 项目的一个容器 包含项目最基本的一些配置 目录名称不建议修改 mybolg 目录下的文件 wsgi.py WSGI(python web server gateway interface) 中文名:python服务器网关接口 python应用与 web 服务器之间的接口 只有我们实现了 wsgi 接口,web 接口才能识别我们的 python 网站,然后才能提供服务,我们才能访问我们用python做的网站。 在项目开发过程中基本上不会用到这个文件。 urls.py URL配置文件 Django 项目中所有地址(页面)都需要我们自己去配置它的 url settings.py 项目的总配置文件 里面包含了数据库,web 应用、时间等各种配置 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 这个是项目的根目录 SECRET_KEY = '4(a3^2tg=+%wxot1lp14kigub*$@98ro498wpk@#+)^6ikw2qv' 这个是安全码,项目要想启动必须要由它。Django 在创建项目的时候会自动生成这个安全码。 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True 这个是调试,但是上方的注释,不要在实际生产中打开它。如果打开,再出现异常的情况向会直接抛给前端。 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] 原装的应用,Django 的项目中是有许多个应用组成的,默认生成的是 Django 自带的应用。 如果我们创建了自己的应用,要把应用写在这个里面,这样才能被 Django 识别。 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] 中间件,Django 自带的工具集。 ROOT_URLCONF = 'myblog.urls' url 的跟文件,指向的是 urls.py 文件。 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] 模板配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } 数据库配置,默认使用的是 sqlite3 数据库。 AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] 跟密码认证有关。 # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True 配置语言,时区等 # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' 静态文件的地址 __init__.py python 中声明模块的文件,一般内容都为空,有了它,我们的 myblog 目录就变成了一个模块。可以在代码中引用。 创建应用 在 pycharm 下方的 Terminal 输入以下命令,也可以在命令行中切换到 myblog 目录下输入以下命令:,我的项目放在了 E 盘: E:\myblog>python manage.py startapp blog 创建之后,我们要把这个应用添加到 setting.py 文件中的 INSTALLED_APPS 里: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', ] 注意:创建的应用名称不可以和 python 中的模块名称相同,否则创建不成功。 blog 的目录结构 blog目录结构 migrations(中文意思是:移植,迁移) 数据移植(迁移)模块,文件夹下的内容由 Django 自动生成的。 admin.py 当前应用的后台管理系统配置 Django 其一的特点是有自己的后台的管理系统,所以每个应用下都有各自的配置文件。 app.py 当前应用的一些配置 models.py 数据模型模块,创建数据表在这个模块中创建的。 使用 OMR 框架,类似于 MVC 结构中的 Models (模型) test.py 自动化测试模块 Django 给我们提供了自动化测试功能,我们在这里编写相应的代码即可针对性进行自动化测试 在这里编写测试脚本(语句) views.py 非常重要的文件,我们每接收一个请求都要响应,响应什么东西,怎么响应都是在这里完成的,处理之后再返回回去。 执行响应的代码所在的模块 代码逻辑处理的主要地点 项目中大部分代码都是在这里编写 创建第一个页面(响应) 1.编辑 blog.views 每个响应对应一个函数,函数必须返回一个响应 函数必须存在一个参数,一般约定为 request 每个响应(函数)对应一个 url from django.shortcuts import render from django.http import HttpResponse # 在 Django 中每个响应都由一个函数来处理 # 因为要处理请求,我们首先要接收一个请求,也就是在函数中传入参数 def index(request): return HttpResponse('Hello this is first request!') 配置url 每个 url 都是以path 的形式写出来 path 函数放在 urlpatterns 列表中 path 函数有三个参数:URL(正则表达式),对应方法,名称 打开 myblog 文件夹下的 urls.py 。 from django.contrib import admin from django.urls import path import blog.views as bv urlpatterns = [ path('admin/', admin.site.urls), path('index/', bv.index), ] 启动服务 点击 pycharm 上方 run 运行 myblog ,或者在命令行切换到 myblog 文件夹下运行 python manage.py runserver 打开浏览器,输入:http://127.0.0.1:8000/index/ 首次响应 第二种 url 配置 根 urls.py 文件中: from django.contrib import admin from django.urls import path,include import blog.views as bv urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include('blog.urls')), ] 在blog 文件下新建 urls.py 文件: #coding=utf-8 from django.urls import path from . import views urlpatterns = [ path('index/', views.index), ] 在根 urls.py 文件中引入 include 在APP应用下,也就是 blog 文件下创建 urls.py 文件,格式跟根 urls.py 相同 根 url.py 文件中 path 函数第二个参数改为 include('blog.urls')注意:根url.py 针对APP配置的URL名称,是该APP的所有 URL总路径 templates介绍 什么是 templates 就是一个一个 HTML 文件 使用了 Django 模板语言(Django Template Language )DTL 可以使用第三方模板(如Jinja2) 在 settings.py 文件中的: TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 第一行修改。 开发第一个 Template 在APP的根目录下创建名叫 Template 的目录 在该目录下创建一个 HTML 文件 html 3.在 views.py 文件中返回一个 render() from django.shortcuts import render from django.http import HttpResponse def index(request): # render 函数通常传入三个参数 # 第一个是请求的对象本身,第二个是模板文件,第三个是传递到前端的数据 return render(request,'index.html') 运行一下项目看看页面: 第一个模板 DTL 初步使用 render() 函数的第三个参数是传递数据到前端的,这个参数支持一个字典 dict 类型的数据。 该字典是后台传递到模板的参数,键位参数名 在模板中使用 {{参数名}} 来直接使用 例: views.py 文件中: def index(request): # render 函数通常传入三个参数 # 第一个是请求的对象本身,第二个是模板文件,第三个是传递到前端的数据 return render(request,'index.html',{'hello':'this is the first template!'}) templates/index.html 文件下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ hello }}!</h1> </body> </html> 页面展示: 展示 再新建一个应用(解决一个小问题) 在 pycharm 下方的 Terminal 输入以下命令,也可以在命令行中切换到 myblog 目录下输入以下命令 E:\myblog>python manage.py startapp blog2 添加应用到 settings.py 中的 INSTALLED_APPS 里 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', 'blog2', ] 接着我们把 blog 里的 templates 文件夹复制到 blog2 中 urls 也复制一份到blog2 中 把两个应用中的templates 中HTML文件改成 <h1>hello blog1</h1> 和 <h1>hello blog2</h1> blog 应用下的 views.py 文件内容复制一份到 blog2 应用下。 根 urls.py 文件中添加: urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include('blog.urls')), path('blog2/', include('blog2.urls')), ] 之后重启项目,我们会发现,在 http://127.0.0.1:8000/blog/index/ 和 http://127.0.0.1:8000/blog2/index/ 上看到的页面是一样的。 这里是 Django 把我们的 index 搞混了。 Django 在查找 template 是按照 INSTALLED_APPS 中的添加顺序查找 template ,如果我们不同应用下的template 下的HTML 文件名字相同,就会造成冲突。不同APP下templates目录下的同名.html文件会造成冲突。 解决templates冲突方案 在APP的templates目录下创建一个以APP名为名称的目录 将HTML文件放入新创建的目录下 再检查一下我们两个应用的 view.py 文件,运行一下,发现正常显示。 models 介绍 models Django 中 models 是什么? 通常,一个model 对应数据库中的一张数据表 Django 中的model 是以类的形式表现 在这个类中包含了一些基本的字段以及数据的一些行为 在 Django 中我们以创建类的形式创建数据表,因此我们在编写代码中,所有对数据的操作,事实上都是对类以及类对象的操作。这样一来,我们就不用写SQL语句了。 ORM 这种方式被称为 ORM :对象关系映射(Object Relation Mapping) 实现了对象和数据库之间的映射 隐藏了数据访问的细节,不需要编写SQL语句 编写 models 在应用的根目录下创建models.py ,并引入models 模块。这一步 Django 已经帮我们创建好了。 在 models.py 文件下创建类,继承 models.Model,该类即是一张数据表 3.在类中创建字段 字段创建 字段即类里面的属性(变量) attr = models.CharField(max_length=64) 更多字段内容 点这里 我们的模型已经创建好了,怎么映射成数据表呢? 映射生成数据表 命令行进入 manage.py 同级目录 也就是当前项目的目录 E:\myblog> 执行 python manage.py makemigrations app(可选)(翻译过来就是制作数据迁移)(可选意味着不选的话,默认所有应用都映射数据表) 再执行 python manage.py migrate E:\myblog>python manage.py makemigrations Migrations for 'blog': blog\migrations\0001_initial.py - Create model Ariticle E:\myblog>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying blog.0001_initial... OK Applying sessions.0001_initial... OK E:\myblog> 这里额外创建的数据表示 Django 自带的应用创建的数据表 查看 Django 会自动在 app/migrations/ 目录下生成移植文件 operations = [ migrations.CreateModel( name='Ariticle', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(default='Title', max_length=32)), ('content', models.TextField(null=True)), ], ), ] 可以看到这里多了一个id字段,我们并没有创建,怎么会有呢?这里是Django 帮我们创建的,因为我们在创建的时候没有指定主键,这里Django 帮我们自动创建了。 执行 python manage.py sqlmigrate 应用名 文件id 查看SQL语句 E:\myblog>python manage.py sqlmigrate blog 0001 BEGIN; -- -- Create model Ariticle -- CREATE TABLE "blog_ariticle" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(32) NOT NULL, "content" text NULL); COMMIT; 默认的sqlite3的数据库在项目的根目录下db.sqlite3 查看并编辑db.sqlite3 使用第三方软件 SQLite Expert Personal 轻量级,完全免费 到这里要安装软件,一篇文章太长也不好。下一篇接着来。

优秀的个人博客,低调大师

Docker Registry私有仓库搭建

Docker Registry 介绍 Docker Registry,它是所有仓库(包括共有和私有)以及工作流的中央Registry。 私有仓库和共有仓库类似,不同之处在于前者不会在搜索结果中显示,也没有访问它的权限。只有用户设置为合作者才能访问私有仓库。 下载镜像并运行 假设主机ip为192.168.1.100 # 下载镜像 [root@localhost ~]# docker pull registry # 启动Docker Registry容器 [root@localhost ~]# docker run -p 15000:5000 -v registry:/var/lib/registry --restart=always --name docker-registry -d registry # 查看Docker Registry进程 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d67e675391bf registry "/entrypoint.sh /e..." 5 weeks ago Up 2 weeks 0.0.0.0:25000->5000/tcp docker-registry 配置客户端Insecure Registry # 编辑文件 vi /etc/docker/daemon.json { "registry-mirrors": ["http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https://registry.docker-cn.com"] , "insecure-registries":["192.168.1.100:25000"] } #重启docker服务 systemctl daemon-reload systemctl restart docker 说明: registry-mirrors 为docker镜像库,配置了国内镜像之后,下载速度会快不少 insecure-registries 为不安全的镜像,我们的Registry配置在这里,push或者pull镜像的机器都需要配置 将Docker镜像推到Registry中 # 给本地镜像打Tag [root@localhost ~]# docker tag centos:latest 192.168.1.100:25000/centos:latest # 推到Registry服务器中 [root@localhost ~]# docker push 192.168.1.100:25000/centos:latest 从Docker Registry下载镜像 [root@localhost ~]docker pull 192.168.1.100:25000/centos:latest 配置Docker Registry管理界面 Docker官方只提供了REST API,并没有给我们一个界面。 可以使用Portus来管理私有仓库, 同时可以使用简单的UI管理工具, Docker提供私有库“hyper/docker-registry-web”, 下载该镜像就可以使用了。 参考 https://hub.docker.com/r/hyper/docker-registry-web/ docker run -d \ -p 8080:8080 \ --name registry-web \ --link docker-registry \ -e REGISTRY_URL=http://docker-registry:5000/v2 \ -e REGISTRY_NAME=localhost:25000 \ hyper/docker-registry-web 访问 http://192.168.1.100:8080 2.png 配置Docker Registry签名证书(待续)

优秀的个人博客,低调大师

使用rancher 搭建docker集群

1.安装docker并配置工作目录 安装docker 以17.03版本为例 [root@Ieat4 ~]# curl https://releases.rancher.com/install-docker/17.03.sh | sh 测试安装是否成功 [root@Ieat4 ~]# sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 添加"youuser"用户到docker组 [root@Ieat4 ~]# sudo usermod -aG docker youuser 添加之后该用户使用docker命令可以不加sudo 设置docker服务开机启动 [root@Ieat4 ~]# systemctl enable docker.service 设置docker挂载盘 通常安装完之后docker的数据目录都在/var/lib/docker 文件夹下面,一般这个都在我们的系统盘下面,系统盘一般比较小而且一旦重装系统很可能面临数据丢失。所以要docker的工作目录映射到我们的数据盘下面,如下: 映射磁盘到目录 假如要映射到/data目录 如果映射到已有目录就跳过下面步骤 新建/data目录 [root@Ieat4 ~]# mkdir /data 假设我们有一块新磁盘尚未映射,下面查看所有磁盘 [root@Ieat4 ~]# fdisk -l 假设查看到/dev/sdb没有被映射,下面我们映射一下 [root@Ieat4 ~]# mount /dev/sdb /data 如果新磁盘有读写保护: mount: /dev/sdb 写保护,将以只读方式挂载 mount: 文件系统类型错误、选项错误、/dev/sdb 上有坏超级块、 缺少代码页或助手程序,或其他错误 有些情况下在 syslog 中可以找到一些有用信息- 请尝试 dmesg | tail 这样的命令看看。 我们先格式化 [root@Ieat4 ~]# mkfs.ext4 /dev/sdb 下面是结果 mke2fs 1.42.9 (28-Dec-2013) /dev/sdb is entire device, not just one partition! 无论如何也要继续? (y,n) y 文件系统标签= OS type: Linux 块大小=4096 (log=2) 分块大小=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 244154368 inodes, 1953234944 blocks 97661747 blocks (5.00%) reserved for the super user 第一个数据块=0 Maximum filesystem blocks=4102029312 59608 block groups 32768 blocks per group, 32768 fragments per group 4096 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848, 512000000, 550731776, 644972544, 1934917632 Allocating group tables: 完成 正在写入inode表: 完成 Creating journal (32768 blocks): 完成 Writing superblocks and filesystem accounting information: 完成 接着再挂载 [root@Ieat4 ~]# mount /dev/sdb /data 查看是否挂载成功,发现已经成功,/data目录有7.3T的可用空间 [root@Ieat4 ~]# df -h /data 文件系统 容量 已用 可用 已用% 挂载点 /dev/sdb 7.3T 23G 6.9T 1% /data 设置开机自动挂载目录,否则重启主机之后,磁盘未自动挂载导致docker服务运行异常,通过往/etc/fstab中追加一条记录来实现 [root@Ieat4 ~]# echo '/dev/sdb /data ext4 defaults 0 0' >> /etc/fstab 查看一下是否写入成功 [root@Ieat4 ~]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Thu Sep 29 14:00:46 2016 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 1 1 UUID=0a7a28d0-04ad-4ed2-912c-bf31fc53b13d /boot xfs defaults 1 2 /dev/mapper/centos-home /home xfs defaults 1 2 /dev/mapper/centos-swap swap swap defaults 0 0 /dev/sdb /data ext4 defaults 0 0 映射docker工作目录 停止docker服务 [root@Ieat4 ~]# service docker stop 将默认docker工作目录移动到/data下,不要使用cp,移动后/var/lib/docker目录应该不存在了才对 [root@Ieat4 ~]# sudo mv /var/lib/docker /data 结果我们要把docker工作目录放在/data/docker下面 [root@Ieat4 ~]# ls /data/docker containers image network overlay plugins swarm tmp trust volumes 建立软连接,文件夹后面不要加 “/”,这样/var/lib/docker即为/data/docker的快捷方式,往/var/lib/docker写的话,实际写入了/data/docker目录 [root@Ieat4 ~]# ln -s /data/docker /var/lib/docker 查看软连接是否成功 [root@Ieat4 ~]# ls -la /var/lib/docker lrwxrwxrwx 1 root root 12 7月 14 17:20 /var/lib/docker -> /data/docker 启动docker sudo service docker start 查看是否正常工作 [root@Ieat4 ~]# sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2.安装rancher-server 注意将所有主机的主机名设置好,一定不要用localhost、127.0.0.1等,以免引起集群网络通讯不通的问题 挑选一台主机192.168.0.101安装,在这里选择rancher-server的1.6版本 [root@Ieat4 ~]# sudo docker run --name rancher-server -d --restart=unless-stopped -p 18180:8080 rancher/server 等待一两分钟后,浏览器访问一下该主机的18180端口,即看到安装成功,进入界面后,按照提示添加主机即可 3.添加主机 比如要添加:192.168.0.106 设置rancher-server ip地址,设置为其他主机可以访问的ip 0.png 点击添加主机 1.png 选择Custom -> 输入要添加主机的ip -> copy docker 命令 2.png 在要添加的主机上运行copy的docker命令 sudo docker run -e CATTLE_AGENT_IP="192.168.0.106" --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.10 http://192.168.0.101:18180/v1/scripts/78D7F7E9398F93E7A5B6:1514678400000:xCO6dhSSWPpVF3bGQXWWVZrvgvE 返回主界面即可看到添加成功

优秀的个人博客,低调大师

Docker + MySQL 主从环境搭建

环境说明 Docker Ubuntu/CentOS MySQL v8.0.11 1. 配置my.cnf my.cnf(部分老版本可能是my.ini)是MySQL核心配置文件。首先,在任意挂载目录下新建*.cnf文件(这里的*代表可以是任意的文件名称)。如果你的mysql是下载安装的,请找到my.cnf并参考如下配置: [mysqld] log-bin=mysql-bin //启用二进制日志 server_id=xxx //xxx代表唯一ID,默认是1。特别注意,当前版本这里是server_id而不是server-id,有些版本可能会不一样 实战示例 在/root/mysql/conf/master/新建master.cnf,配置如下: [mysqld] log-bin=mysql-bin server_id=100 在/root/mysql/conf/slave/新建slave.cnf,添加如下: [mysqld] log-bin=mysql-bin server_id=200 2. 运行MySQL 2.1 master(主库) docker run --name mysql-master -v /root/mysql/conf/master:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -p 10000:3306 -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 2.2 slave(从库) docker run --name mysql-slave -v /root/mysql/conf/slave:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -p 10001:3306 -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 注意,当前mysql版本是8.0.11,不同的版本之间可能存在差别,docker可以拉取指定版本的mysql Image,命令:docker pull mysql:8.0.11 3. 新建账号 3.1 在 master 上创建复制账号 // 1.进入主库容器 docker exec -it mysql-master bash // 2.登录mysql mysql -uroot -proot // 3.rep表示复制账号;<salve_ip>可修改为%,代表任意的主机;`IDENTIFIED BY`后面代表rep用户的认证密码 CREATE USER 'rep'@'<salve_ip>' IDENTIFIED WITH mysql_native_password BY 'reppassword'; GRANT REPLICATION SLAVE ON *.* TO 'rep'@'<salve_ip>'; 3.2 获取并记录File和Position信息 执行show master status;即可 master status 4. 配置连接 配置 slave 连接 master // 1.进入从库容器 docker exec -it mysql-slave bash // 2.登录mysql mysql -uroot -proot // 3.配置主库认证信息,<File>和<Position>同上 CHANGE MASTER TO MASTER_HOST='<master_ip>',MASTER_PORT=10000,MASTER_USER='rep',MASTER_PASSWORD='reppassword',MASTER_LOG_FILE='<File>',MASTER_LOG_POS=<Position>; 5. 开启同步 开启同步 在 slave 上启动线程:start slave; 查看状态 在 slave 上执行命令:show slave status\G; 查看复制状态 6. 相关命令 设置从库只读:set global read_only=1;。1表示只读,0是读写,但对拥有super权限的账号是不生效的,所以在授权账号的时候应尽量避免添加super权限 查看读写情况:show global variables like "%read_only%"; 查看server_id:show variables like '%server_id%'; 7. 踩坑记录 执行show slave status\G;,发现从库并没有连接上主库,留意到错误信息大致为:“主从库server_id不能一致”,随即查看新增的master.cnf和slave.cnf,但并没有发现问题,随即用docker logs mysql-master查看启动日志,有一行警告大概是这样的:mysql: [Warning] World-writable config file '/etc/mysql/conf.d/master.cnf' is ignored.,这说明配置文件并没有挂载成功,搜索后得知当文件权限全局可写时,mysql会担心这种文件被其他用户恶意修改,所以会忽略掉这个配置文件,修改文件权限chmod 644 *.cnf后,再将以上流程重新跑了一遍,问题没有复现。

优秀的个人博客,低调大师

Docker + PostgreSQL 主从环境搭建

环境说明 Docker Ubuntu/CentOS PostgreSQL v10.1 1. 运行PostgreSQL 1.1 主库 docker run --name pgsmaster -p 5500:5432 -e POSTGRES_PASSWORD=pgsmaster -v $(pwd)/pgsmaster:/var/lib/postgresql/data -d postgres 1.2 从库 docker run --name pgsslave -p 5501:5432 -e POSTGRES_PASSWORD=pgsslave -v $(pwd)/pgsslave:/var/lib/postgresql/data -d postgres 进入以上主、从库对应的实际挂载目录执行下面的操作 2. 配置master(主库) 2.1 编辑pg_hba.conf,在最下面添加如下: // replication_username: 复制账号; slave_ip: 从库所在的服务器ip host replication <replication_username> <slave_ip>/32 md5 2.2 编辑postgresql.conf(亲测,非必须),更改如下: synchronous_standby_names = '*' 2.3 进入容器,登录PostgreSQL,创建复制账号并验证: # 1.进入容器 docker exec -it pgsmaster bash # 2.连接PostgreSQL psql -U postgres # 3.创建用户 set synchronous_commit =off; // replication_username: 对应上面设置的复制账号; replication_username_password: 认证密码 create role <replication_username> login replication encrypted password '<replication_username_password>'; # 4.验证用户 \du 3. 配置Slave(从库) 3.1 编辑postgresql.conf(亲测,非必须),更改如下: hot_standby_feedback = on 3.2 新建recovery.conf,添加如下内容: standby_mode = 'on' // replication_username: 复制账号(同主库); master_ip: 主库所在的服务器ip; master_port: 主库端口; replication_username_password: 认证密码 primary_conninfo = 'host=<master_ip> port=<master_port> user=<replication_username> password=<replication_username_password>' 4. 同步主从库数据及测试 4.1 停止PostgreSQL docker stop pgsmaster docker stop pgsslave 4.2 同步主从库数据(必须) 方法1:rsync // 1.1 已ssh认证,请将$(pwd)更改为实际的路径 rsync -cva --inplace --exclude=*pg_xlog* $(pwd)/pgsmaster/ <slave_ip>:$(pwd)/pgsslave/ // 1.2 无ssh认证,请将$(pwd)更改为实际的路径 rsync -cva --inplace --exclude=*pg_xlog* $(pwd)/pgsmaster/ ssh root@<slave_ip>:$(pwd)/pgsslave/ 方法2:pg_basebackup(自行谷歌) 4.3 先后启动主库、从库服务 docker start pgsmaster docker start pgsslave 4.4 连接测试 // 进入主库容器 docker exec -it pgsmaster bash // 查看复制状态 psql -U postgres -x -c "select * from pg_stat_replication;" 查看复制状态

优秀的个人博客,低调大师

CentOS 7搭建LAMP环境

一、检查环境 1.查看centos版本 [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [root@localhost ~]# 2.检查是否安装相关应用 检查apache [root@localhost ~]# service httpd status Redirecting to /bin/systemctl status httpd.service Unit httpd.service could not be found. [root@localhost ~]# 没找到httpd.service说明没有安装apache 检查mysql [root@localhost ~]# service mysqld status Redirecting to /bin/systemctl status mysqld.service Unit mysqld.service could not be found. [root@localhost ~]# 同上,没有安装mysql 二、安装apache [root@localhost ~]# yum -y install httpd 安装成功返回如下: 图片.png 安装apache扩展 [root@localhost ~]# yum -y install httpd-manual.noarch mod_ssl 安装成功返回如下: 图片.png 三、安装php [root@localhost ~]# yum -y install php 安装成功返回如下: 图片.png 安装php-fpm [root@localhost ~]# yum -y install php-fpm 安装成功返回如下: 图片.png 安装php扩展 [root@localhost ~]# yum -y install php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc php-devel 图片.png 安装成功返回如下: 图片.png 四、安装mysql [root@localhost ~]# yum -y install mysql 安装成功返回如下: 可以看到CentOS7安装mysql时候安装的是 mariadb,这是因为mysql被Sun公司收购了,Sun公司又被Oracle收购了,成功了商业的应用,然后mysql停止开源,所以mysql之父又开发了mariadb数据库,mariadb数据库兼容了mysql所有的内容,总之就是换了个名字,和之前mysql使用没有太大区别。 安装mysql-server 图片.png 出错了不要紧,原因上面已经说明了,然后将mysql换成mariadb就好了,下面继续安装: [root@localhost ~]# yum -y install mariadb-server 安装成功返回如下: 图片.png 安装php-mysql [root@localhost ~]# yum -y install php-mysql 安装成功返回如下: 图片.png 安装mysql扩展 [root@localhost ~]# yum -y install mysql-connector-odbc libdbi-dbd-mysql 安装成功返回如下: 图片.png [root@localhost ~]# yum -y install mariadb-devel 图片.png

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat

Apache Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。