摘要:?Polardb 是阿里云研發的一種關系型數據庫,與mysql完全兼容,而性能又是其6倍,具有高吞吐,低延遲等特性; 本測試通過模擬控制智能家居開關的終端場景,來體驗polardb的性能;
本文由阿里云 MVP 洵云提供。
Polardb 是阿里云研發的一種關系型數據庫,與mysql完全兼容,而性能又是其6倍,具有高吞吐,低延遲等特性;
本測試通過模擬控制智能家居開關的終端場景,來體驗polardb的性能;
1、環境搭建
1.1 polardb配置
首先需要購買polardb,按照處理器和內存的性能不同,價格也不同,最低的配置為2核4G的polar.mysql.x2.medium規格,包月價格560RMB;
購買以后,就可以通過連接https://polardb.console.aliyun.com/,進入polardb控制臺進行相關的配置;選擇一個地域節點[如華東1],創建一個實例,然后選擇一個集群列表,創建一個集群。創建好后,可以看到數據庫類型為POLARDB (MySQL 5.6),付費類型和到期時間分別為包月和一個月的長度;在創建時配置好初始賬號和密碼就可以使用了;在集群頁面,鼠標點擊右側的管理連接,進入集群信息頁面,可以看到公網聯接的地址,是用戶賬號名開始的連接,后面是mysql常用的端口號3306,記錄下這個后面連接用的到;
集群連接地址 (公網) : mypolardb.mysql.polardb.rds.aliyuncs.com:3306 ,這里我的賬號配置為mypolardb,所以這里以mypolardb開頭;
在上面的白名單列表 中,點擊后面的筆狀修改按鈕,將我們用來連接數據庫的ecs 服務器地址添加到里面;這里我的服務器地址為47.94.219.162.
1.2 ECS服務器配置:
由于需要在web頁面上進行結果測試,先安裝nginx服務器,使用以下命令行進行安裝:
sudo apt-get install nginx?
安裝好后,在瀏覽器中輸入 ECS的地址[這里測試的是:47.94.219.162],可以看到nginx的歡迎界面,表示安裝成功;
由于后面需要用php腳本程序開發,所以還需要安裝php,在console窗口輸入以下命令安裝:
sudo apt-get install php*
安裝好后,輸入下面的命令修改nginx的配置:
sudo vi /etc/nginx/sites-available/default
將文件中的下面四段打開:
location ~ \.php$ {
? ?include snippets/fastcgi-php.conf;
? ?fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
保存退出,然后重啟nginx:
service nginx restart
進入/var/www/html目錄,創建一個php文件,測試是否php安裝成功:
vi phpinfo.php
在瀏覽器訪問這個文件,如果可以看到相關的php信息,則表明php安裝成功;
進入域名控制臺,選擇要解析的域名,點擊解析連接,添加一條A記錄,主機記錄起一個容易記住的名字,比如:polardb,記錄值選擇ECS的ip地址,比如:47.94.219.162,然后創建完成后,等待5分鐘,在瀏覽器訪問一下新的域名,比如polardb.xunyun17.xyz,如果同樣能看到nginx 的歡迎界面,表示域名解析成功;
由于本智能家居場景使用mysql開發體驗,所以還需要在ubuntu里,安裝mysql,運行下面的命令進行安裝:
sudo apt install mysql-client
安裝完mysql后,建立一個shell腳本,測試是否可以連接到polardb上:
vi p.sh
mysql -h mypolardb.mysql.polardb.rds.aliyuncs.com --user=mypolardb --password=mypolardb
./p.sh
如果運行完腳本后,可以看到mysql的提示信息,和mysql大于號提示符,表示可以連接成功;
2、開發
首先搭建創建一個數據庫和一張表用來保存客廳和設備當前信息:
./p.sh
create database keting;
use keting;
CREATE TABLE status (devname VARCHAR(20), value int(4),changetime DATETIME);
insert into status(devname,value,changetime) values?
('TV0001',0,NOW()),?
('LAMP01',1,NOW()),
('CURN01',1,NOW());?
然后通過mysql的c語言api接口,編寫一段程序,來讀取status設備表中的設備狀態:
////////////////////////////////////////query lamp device
? ? ?sprintf(str_cmd,"select value from status where devname='LAMP01'");
//printf("\n%s\n.",str_cmd);
? ? ?no_res = 0;
?
? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? res = mysql_use_result(conn);
?if(no_res==0){
? ? ?while((row = mysql_fetch_row(res)) != NULL)
? ? ?{
//? ? ? ? printf("%s \n", row[0]);
? ?if(selno==17) printf("%s", row[0]);
?else? ? ? ? ?printf("%s\t %s\t %s", row[0],row[1],row[2]);
? ? ?}
? }?
? ? mysql_free_result(res);
? ? ?sprintf(str_cmd,"select value from status where devname='CURN01'");
//printf("\n%s\n.",str_cmd);
? ? ?no_res = 0;
下一步,就是用php腳本調用這段代碼查詢設備狀態,并且顯示在網頁上:查詢結果在
?使用以下php代碼實現:
?if(!empty($_REQUEST['arguments'])){
? ? exec('./mysqlv '.$_REQUEST['arguments'].' LAMP03 1',$result);
//print_r($result);
//echo $result[0][0].'
';
//echo $result[0][1].'
';
//echo $result[0][2];
if($result[0][0]==0) $s1 = 'OFF';
else $s1 = 'ON';
if($result[0][1]==0) $s2 = 'OFF';
else $s2 = 'ON';
if($result[0][2]==0) $s3 = 'OFF';
else $s3 = 'ON';
? ? if($_REQUEST['arguments']==17) echo "
| 電視 | 燈 | 窗簾 |
|---|---|---|
| ".$s1." | ".$s2." | ".$s3." |
打開瀏覽器運行這個php腳本,點擊運行按鈕,可以看到頁面會顯示一個設備狀態表格,包括電視,燈,窗簾是否有打開或關閉;
接下來,用c語言寫一個socket監聽程序,用來監聽后續遠程設備對智能家居的更新請求,并實現狀態更新,代碼如下:
? ?n = read(sock,buffer,255);
?if (n < 0) {
? ? ? perror("ERROR reading from socket");
? ? ? exit(1);
? ?}
strncpy(devname,buffer,6);
devname[6]=0;
devval=buffer[6]-'0';
memset(cmdstr,0,256);
sprintf(cmdstr,"./mysqlv 15 %s %i",devname,devval);
printf("%s.\n",cmdstr);
? ?system(cmdstr);
? ? ?
? ?printf("Here is the message: %s\n",buffer);
? ?n = write(sock,"I got your message",18);
?
服務端監聽程序編寫好以后,就可以開始寫模擬設備端的程序:
同樣使用c語言的socket函數進行編寫,將命令行的數據發往服務器端:
? ?/* Now connect to the server */
? ?if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
? ? ? perror("ERROR connecting");
? ? ? exit(1);
? ?}
? ?
? ?/* Now ask for a message from the user, this message
? ? ? * will be read by server
? ?*/
? ?printf("Please enter the message: ");
? ?bzero(buffer,256);
? ?strcpy(buffer, argv[3]);
? ?//fgets(buffer,255,stdin);
? ?
? ?/* Send message to the server */
? ?n = write(sockfd, buffer, strlen(buffer));
? ?
? ?if (n < 0) {
? ? ? perror("ERROR writing to socket");
? ? ? exit(1);
? ?}
? ?
最后,還要修改我們的mysqlv.c的數據庫調用代碼,將命令行參數更改到數據庫中:
?sprintf(str_cmd,"update status set value=%d? where devname=\'%s\'",atoi(argc[3]),argc[2]);
?
3、測試
當服務器和客戶端的程序都完成后,就可以進行測試了;首先在服務器上,用以下命令行后臺運行監聽程序:
./s&
然后在本地運行模擬設備程序,例如我們要運行將燈打開的命令,用下面的命令行:
./c 47.94.219.162 8266 LAMP011
如果收到服務器的回顯消息,則表示發送成功;
打開瀏覽器,運行php腳本,點擊運行按鈕,可以看到頁面出現了最新設備狀態的表格信息;
結論與建議:可以看到這個polardb的新型數據庫,還是和mysql兼容的,操作起來也比較方便;
如果能夠像其他阿里云的產品也提供相關的restful api接口,將會使開發變得更方便和快捷;
4、附錄和截圖
操作polardb 的mysqlv完整程序:
#include
#include
#include
#include
?
int main(int argv,char**argc)
{
? ? MYSQL *conn;
? ? MYSQL_RES *res;
? ? MYSQL_ROW row;
?
? ? char server[] = "47.98.24.120";
? ? char user[] = "mypolardb";
? ? char password[] = "mypolardb";
? ? char database[] = "mysql";
char str_cmd[250];?
int no_res = 0;
int selno=0;
?if(argv<2) {
printf("mysqlv funcno.\n");
return 0;
}
? ? conn = mysql_init(NULL);
?
? ? if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))
? ? {
? ? ? ? printf(">>>>>>>\n");
? ? ? ? exit(1);
? ? }
selno = atoi(argc[1]);
? ? //? ? printf("selno:%d\n
",selno);
switch(selno){
? ?case 1:
? ? ?strcpy(str_cmd,"select version()");
? ? ?break;
? ?case 2:
? ? ?strcpy(str_cmd,"select current_date");
? ? ?break;
? ?case 3:
? ? ?strcpy(str_cmd,"show databases");
? ? ?break;
? ?case 4:
? ? ?strcpy(str_cmd,"create database keting");
? ? ?no_res = 1;
? ? ?break;
? ?case 5:
? ? ?strcpy(str_cmd,"drop database keting");
? ? ?no_res = 1;
? ? ?break;
? ?case 6:
? ? ?strcpy(str_cmd,"create database woshi");
? ? ?no_res = 1;
? ? ?break;
? ?case 7:
? ? ?strcpy(str_cmd,"drop database woshi");
? ? ?no_res = 1;
? ? ?break;
? ?case 8:
? ? ?strcpy(str_cmd,"create database chufang");
? ? ?no_res = 1;
? ? ?break;
? ?case 9:
? ? ?strcpy(str_cmd,"drop database chufang");
? ? ?no_res = 1;
? ? ?break;
? ?case 10:
? ? ?strcpy(str_cmd,"use keting");
? ? ?no_res = 1;
? ? ?break;
? ?case 11:
? ? ?strcpy(str_cmd,"use woshi");
? ? ?no_res = 1;
? ? ?break;
? ?case 12:
? ? ?strcpy(str_cmd,"use chufang");
? ? ?no_res = 1;
? ? ?break;
#if 0
? ?case 13:
? ? ?strcpy(str_cmd,"show tables");
? ? ?//no_res = 1;
? ? ?break;
/*table operate for keting*/
? ?case 14:
? ? ?strcpy(str_cmd,"CREATE TABLE prop (devname VARCHAR(20), value int(4))");
? ? ?//no_res = 1;
? ? ?break;n
#endif
? ?case 15:
? ? ?strcpy(str_cmd,"describe prop");
? ? ?//no_res = 1;
? ? ?break;
? ?case 16:
? ? ?strcpy(str_cmd,"drop table if exists prop");
? ? ?//no_res = 1;
? ? ?break;
}
if(selno==13){
? ? ?strcpy(str_cmd,"use keting");
? ? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? ?strcpy(str_cmd,"show tables");
? ? ?no_res = 0;
?}
if(selno==14){
? ? ?strcpy(str_cmd,"use keting");
? ? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? ?strcpy(str_cmd,"select * from prop;");
? ? ?no_res = 0;
?}
if(selno==15){
? ? ?strcpy(str_cmd,"use keting");
? ? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
//? ? ?sprintf(str_cmd,"insert into prop(devname,value,changetime) values (\'%s\',%i,NOW())",argc[2],atoi(argc[3]));
? ? ?sprintf(str_cmd,"update status set value=%d? where devname=\'%s\'",atoi(argc[3]),argc[2]);
printf("\n%s\n.",str_cmd);
? ? ?no_res = 1;
?}
if(selno==16){
? ? ?strcpy(str_cmd,"use keting");
? ? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? ?sprintf(str_cmd,"delete from prop where devname='my_dev'");
printf("\n%s\n.",str_cmd);
? ? ?no_res = 1;
?}
if(selno==17){
? ? ?strcpy(str_cmd,"use keting");
? ? ?if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ? ?}
////////////////////////////////////////query tv device
? ? ?sprintf(str_cmd,"select value from status where devname='TV0001'");
//printf("\n%s\n.",str_cmd);
? ? ?no_res = 0;
?
? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? res = mysql_use_result(conn);
?if(no_res==0){
? ? ?while((row = mysql_fetch_row(res)) != NULL)
? ? ?{
//? ? ? ? printf("%s \n", row[0]);
? ?if(selno==17) printf("%s", row[0]);
?else? ? ? ? ?printf("%s\t %s\t %s", row[0],row[1],row[2]);
? ? ?}
? }?
? ? mysql_free_result(res);
////////////////////////////////////////query lamp device
? ? ?sprintf(str_cmd,"select value from status where devname='LAMP01'");
//printf("\n%s\n.",str_cmd);
? ? ?no_res = 0;
?
? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? res = mysql_use_result(conn);
?if(no_res==0){
? ? ?while((row = mysql_fetch_row(res)) != NULL)
? ? ?{
//? ? ? ? printf("%s \n", row[0]);
? ?if(selno==17) printf("%s", row[0]);
?else? ? ? ? ?printf("%s\t %s\t %s", row[0],row[1],row[2]);
? ? ?}
? }?
? ? mysql_free_result(res);
? ? ?sprintf(str_cmd,"select value from status where devname='CURN01'");
//printf("\n%s\n.",str_cmd);
? ? ?no_res = 0;
??
}
//printf("finish! \n");
? ? if(mysql_query(conn, str_cmd))
? ? ?{
? ? ? ? printf("<<<<<<<\n");
? ? ? ? exit(1);
? ?}
? ? res = mysql_use_result(conn);
?if(no_res==0){
? ?if(selno==14)
? ? ?printf("DEVICE VALUE TIMESTAMP
");
? ? ?while((row = mysql_fetch_row(res)) != NULL)
? ? ?{
//? ? ? ? printf("%s", row[0]);
if(selno==17) printf("%s\t ", row[0]);
?else? ? ? ?printf("%s\t %s\t %s", row[0],row[1],row[2]);
? ? ?}
? }?
? ? mysql_free_result(res);
? ? mysql_close(conn);
/*?
? ? printf("finish! \n");
? ? printf("finish!
");
?*/
? ? return 0;
}
server.c服務器監聽的完整程序:
#include
#include
#include
#include
#include
void doprocessing (int sock);
int main( int argc, char *argv[] ) {
? ?int sockfd, newsockfd, portno, clilen;
? ?char buffer[256];
? ?struct sockaddr_in serv_addr, cli_addr;
? ?int n, pid;
? ?
? ?/* First call to socket() function */
? ?sockfd = socket(AF_INET, SOCK_STREAM, 0);
? ?
? ?if (sockfd < 0) {
? ? ? perror("ERROR opening socket");
? ? ? exit(1);
? ?}
? ?
? ?/* Initialize socket structure */
? ?bzero((char *) &serv_addr, sizeof(serv_addr));
? ?portno = 8266;//5001;
? ?
? ?serv_addr.sin_family = AF_INET;
? ?serv_addr.sin_addr.s_addr = INADDR_ANY;
? ?serv_addr.sin_port = htons(portno);
? ?
? ?/* Now bind the host address using bind() call.*/
? ?if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
? ? ? perror("ERROR on binding");
? ? ? exit(1);
? ?}
? ?
? ?/* Now start listening for the clients, here
? ? ? * process will go in sleep mode and will wait
? ? ? * for the incoming connection
? ?*/
? ?
? ?listen(sockfd,5);
? ?clilen = sizeof(cli_addr);
? ?
? ?while (1) {
? ? ? newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
? ? ? if (newsockfd < 0) {
? ? ? ? ?perror("ERROR on accept");
? ? ? ? ?exit(1);
? ? ? }
? ? ??
? ? ? /* Create child process */
? ? ? pid = fork();
? ? ? if (pid < 0) {
? ? ? ? ?perror("ERROR on fork");
? ? ? ? ?exit(1);
? ? ? }
? ? ??
? ? ? if (pid == 0) {
? ? ? ? ?/* This is the client process */
? ? ? ? ?close(sockfd);
? ? ? ? ?doprocessing(newsockfd);
? ? ? ? ?exit(0);
? ? ? }
? ? ? else {
? ? ? ? ?close(newsockfd);
? ? ? }
? ?} /* end of while */
}
void doprocessing (int sock) {
? ?int n;
? ?char buffer[256];
? ?char cmdstr[256];
? ?char devname[10];
? ?int devval=0;
? ?bzero(buffer,256);
? ?n = read(sock,buffer,255);
?if (n < 0) {
? ? ? perror("ERROR reading from socket");
? ? ? exit(1);
? ?}
strncpy(devname,buffer,6);
devname[6]=0;
devval=buffer[6]-'0';
memset(cmdstr,0,256);
sprintf(cmdstr,"./mysqlv 15 %s %i",devname,devval);
printf("%s.\n",cmdstr);
? ?system(cmdstr);
? ? ?
? ?printf("Here is the message: %s\n",buffer);
? ?n = write(sock,"I got your message",18);
? ?
? ?if (n < 0) {
? ? ? perror("ERROR writing to socket");
? ? ? exit(1);
? ?}
if(buffer[0]=='z') exit(1);
}
client.c客戶端模擬設備的完整程序:
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
? ?int sockfd, portno, n;
? ?struct sockaddr_in serv_addr;
? ?struct hostent *server;
? ?
? ?char buffer[256];
? ?
? ?if (argc < 3) {
? ? ? fprintf(stderr,"usage %s hostname port devsw\n", argv[0]);
? ? ? exit(0);
? ?}
? ?portno = atoi(argv[2]);
? ?
? ?/* Create a socket point */
? ?sockfd = socket(AF_INET, SOCK_STREAM, 0);
? ?
? ?if (sockfd < 0) {
? ? ? perror("ERROR opening socket");
? ? ? exit(1);
? ?}
? ?server = gethostbyname(argv[1]);
? ?
? ?if (server == NULL) {
? ? ? fprintf(stderr,"ERROR, no such host\n");
? ? ? exit(0);
? ?}
? ?
? ?bzero((char *) &serv_addr, sizeof(serv_addr));
? ?serv_addr.sin_family = AF_INET;
? ?bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
? ?serv_addr.sin_port = htons(portno);
? ?
? ?/* Now connect to the server */
? ?if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
? ? ? perror("ERROR connecting");
? ? ? exit(1);
? ?}
? ?
? ?/* Now ask for a message from the user, this message
? ? ? * will be read by server
? ?*/
? ?printf("Please enter the message: ");
? ?bzero(buffer,256);
? ?strcpy(buffer, argv[3]);
? ?//fgets(buffer,255,stdin);
? ?
? ?/* Send message to the server */
? ?n = write(sockfd, buffer, strlen(buffer));
? ?
? ?if (n < 0) {
? ? ? perror("ERROR writing to socket");
? ? ? exit(1);
? ?}
? ?
? ?/* Now read server response */
? ?bzero(buffer,256);
? ?n = read(sockfd, buffer, 255);
? ?
? ?if (n < 0) {
? ? ? perror("ERROR reading from socket");
? ? ? exit(1);
? ?}
? ?printf("%s\n",buffer);
? ?return 0;
}
p.php腳本結果顯示的完整程序;
? ?
? ?
? ? ? ? if(!empty($results)){
? ? ? ? //? ? echo $results;
? ? ? ? }
? ? ?>
? ?
? ?
if(!empty($_REQUEST['arguments'])){
? ? exec('./mysqlv '.$_REQUEST['arguments'].' LAMP03 1',$result);
//print_r($result);
//echo $result[0][0].'
';
//echo $result[0][1].'
';
//echo $result[0][2];
if($result[0][0]==0) $s1 = 'OFF';
else $s1 = 'ON';
if($result[0][1]==0) $s2 = 'OFF';
else $s2 = 'ON';
if($result[0][2]==0) $s3 = 'OFF';
else $s3 = 'ON';
? ? if($_REQUEST['arguments']==17) echo "
| 電視 | 燈 | 窗簾 |
|---|---|---|
| ".$s1." | ".$s2." | ".$s3." |
}
?>
阿里云雙十一1折拼團活動:已滿6人,都是最低折扣了
【滿6人】1核2G云服務器99.5元一年298.5元三年 2核4G云服務器545元一年 1227元三年
【滿6人】1核1G MySQL數據庫 119.5元一年
【滿6人】3000條國內短信包 60元每6月
參團地址:http://click.aliyun.com/m/1000020293/
電子發燒友App














































評論