Donwload: 大型商业级代驾业务全流程落地 - 搭建数据库集群
数据库切分顾名思义,就是将数据库拆成多个,主要有两种方式
1.垂直切分
垂直切分就是将表按照不同的业务,分散存储到各个数据库。这是一个按业务维度的切分方式。
优点:垂直切分后数据库业务逻辑会非常清晰,拆分的规则也是根据业务来,数据库维护也很简单。
缺点:垂直切分后,由于表分散到了各个数据库,导致事务处理会很麻烦。
2.水平切分
水平切分是在垂直切分条件下,若有数据量较大或并发量较高的数据表,可以将其的数据量进行切分,分散存到多个数据库。
优点:不存在单库大数据,高并发的性能瓶颈。
缺点:数据多次扩展难度和维护量极大。
针对这两种分库策略,mycat将它们的优点整合起来,使得更加可用。
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">0</property>
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">1</property>
<!--
单位为m
-->
<property name="memoryPageSize">1m</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">true</property>
</system>
<user name="root">
<property name="password">root</property>
<property name="schemas">test</property>
</user>
</mycat:server>
大型商业级代驾业务全流程落地 - 多端全栈项目实战开发
一、实现后台数据实时更新博客文章列表 怎么才能只是修改数据库,动态更新列表呢? 这里就用到了node的koa框架,这个框架我个人认为比较方便,比express好多了。 其实作用也大差不差,对了,这里还用到了mysql,这个比较简单,不用细讲。 这里主要是使用了koa2-cors模块实现跨域,koa-router是用来做接口的。 下面是一段我后台的代码,只放一部分有关的代码。
var Koa = require('koa');
var Router = require('koa-router' );
var cors = require('koa2-cors');
var mysql = require('mysql');
var app = new Koa();
var router = new Router();
// 跨域
const allowOrigins = [
"http://localhost:8080"
];
app.use(cors({
origin: function(ctx) {
if (allowOrigins.includes(ctx.header.origin)) {
return ctx.header.origin;
}
return false;
},
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
maxAge: 5,
credentials: true,
withCredentials:true,
allowMethods: ['GET', 'POST', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));
// 数据库信息
var connection = mysql.createConnection({
host : 'xxxxxxxx',
port:3306,
user : 'root',
password : 'xxxxx',
database : 'url'
});
connection.connect();
// 数据库操作
const query = function (sql) {
return new Promise((resolve, reject) => {
connection.query(sql, function (error, results) {
if(error){
reject(error);
}else{
resolve(results)
}
});
})
}
// 获取url
router.get( '/csdnurl', async(ctx, next) => {
var sql = "select * from csdnurl";
let results = await query(sql);
ctx.body=results
});
//使用路由中间件
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(5300);
console.log('服务器运行中')
这样只需要修改数据库的数据,前台循环就可以完美的展现了,这个问题有点简单啊。
二、如何实现访问量保存,以及异步展现 保存访问量无非就是把一个变量每加载页面的时候+1操作,然后将变量存在数据库中,可以如果用户不断刷新页面,那么这个访问量不就成为虚设了吗? 这个问题需要前台考虑,我们先考虑下把数据存起来。
router.post('/post', (ctx, next) => {
var modSql = 'UPDATE user SET count = ? WHERE id = ?';
var modSqlParams = [ctx.request.body.count, 1];
connection.query(modSql, modSqlParams,function(err, result) {
if (err) {
console.log('[INSERT ERROR] - ', err.message);
return;
}
console.log('INSERT ID:', result.insertId);
});
ctx.body = ctx.request.body // echo the result back
});
// 获取浏览量
router.get('/get', async (ctx, next) => {
var sql = "select * from user where count";
let results = await query(sql);
ctx.body=results
});
每次访问+1发送数据,保存在数据库中,然后下次访问时不再增加,因为是同一个用户。 这里需要注意的是,我们原来使用express框架里使用mysql时,可以在回调函数中获取result,并且可以返回到页面里,可是这里就取不到了。我们如何解决呢?这里我们用到了async 、await 。这是es6的语法,async/await是一个用同步思维解决异步问题的方案(等结果出来之后,代码才会继续往下执行)。 这里封装了mysql的收发操作。
// 数据库操作
const query = function (sql) {
return new Promise((resolve, reject) => {
connection.query(sql, function (error, results) {
if(error){
reject(error);
}else{
resolve(results)
}
});
})
}
var json = {};
const query1 = function (userStr,name,passwd,token1) {
return new Promise((resolve, reject) => {
connection.query(userStr, function (error, result) {
if(error){
reject(error);
}else{
if (result.length > 0) {
json['message'] = '用户已经存在';
json['resultCode']= 1;
} else {
json['message'] = '注册成功';
json['token'] = token1;
json['resultCode'] = 200;
var insertStr = `insert into login (username, password,token) values ("${name}", "${passwd}","${token1}")`;
console.log(insertStr)
connection.query(insertStr, function (err, res) {
if (err) throw err;
})
}
resolve(json)
}
});
})
}
这样我们使用async/await解决了异步的问题。
三、 实现登录注册,以及登录后留言 其实这个放在最后,有点欠妥,虽然也是个功能,不过,难点没什么好讲的。 主要是实现了第二个难点,下面就好办了。
// 获取留言
router.get('/mesed', async (ctx, next) => {
var sql = "select * from data";
let results = await query(sql);
ctx.body=results
});
// 发送留言
router.post('/mes', (ctx, next) => {
var user = ctx.request.body.user;
var mes = ctx.request.body.mes;
var userStr = `insert into data (user, mes) values ("${user}", "${mes}")`
connection.query(userStr, function (err, result) {
if (err) {
console.log('[INSERT ERROR] - ', err.message);
return;
}
console.log('INSERT ID:', result.insertId);
});
ctx.body = ctx.request.body // echo the result back
});
最后,还要注意几个小点,async/await在node使用时一定要升级最新版本,否则不能用。还有,在koa实现下线上https服务, 下面一段代码就可以解决
var https=require("https");//https服务
var fs= require("fs");
var Koa = require('koa');
var enforceHttps = require('koa-sslify').default;//这里是关键哦
var app = new Koa();
app.use(enforceHttps());
var options = {
key: fs.readFileSync('./2_xxx.key'),
cert: fs.readFileSync('./1_xxx_bundle.crt')
}
https.createServer(options, app.callback()).listen(5300);
console.log('服务器运行中')