Utak + VPS para sa 30 rubles =?

Napakasarap kapag ang lahat ng kinakailangang maliliit na bagay ay nasa kamay: isang magandang panulat at notepad, isang matalas na lapis, isang komportableng mouse, isang pares ng mga karagdagang wire, atbp. Ang mga hindi kapansin-pansing bagay na ito ay hindi nakakaakit ng pansin, ngunit nagdaragdag ng ginhawa sa buhay. Ang parehong kuwento ay may iba't ibang mga mobile at desktop application: para sa mahabang screenshot, para sa pagpapaliit ng laki ng isang larawan, para sa pagkalkula ng mga personal na pananalapi, mga diksyunaryo, mga tagasalin, mga nagko-convert, atbp. Mayroon ka ba? VPS - alin ang mura, laging nasa kamay at nagdudulot ng maraming benepisyo? Hindi, hindi ang mayroon ka sa iyong kumpanya, kundi ang sarili mong "bulsa". Naisip namin na kung walang maliit na VPS sa 2019 ay malungkot ito, tulad ng walang karaniwang fountain pen sa isang lecture. Bakit malungkot? Tag-init na. kamusta summer? Tag-init para sa isang espesyalista sa IT: nakaupo sa bahay, nagtatrabaho sa iyong mga paboritong proyekto nang walang anumang pagsisisi. Sa pangkalahatan, naisip at ginawa namin ito.

Utak + VPS para sa 30 rubles =?
Dumating na ang komunismo, mga kasama.

Ganyan siya - ang VPS namin for thirty

Marami kaming nabasang artikulo mula sa mga kakumpitensya at user na sumulat 3-4 taon na ang nakakaraan tungkol sa kung bakit hindi kailangan ang murang VPS. Well, tama, pagkatapos ang VPS "para sa isang sentimos" ay purong marketing at hindi maaaring mag-alok ng mga normal na pagkakataon sa pagtatrabaho. Ngunit ang mga oras ay nagbabago, ang halaga ng mga virtual na mapagkukunan ay nagiging mas mababa at mas mababa, at para sa 30 rubles sa isang buwan handa kaming mag-alok nito:

  • Processor: Intel Xeon 2 GHz (1 core)
  • Linux system (Debian, Ubuntu, CentOS na mapagpipilian)
  • 1 nakalaang IPv4 address
  • 10 GB ng data storage sa mabilis na enterprise-class SSD drive
  • RAM: 512 MB
  • Bawat segundong pagsingil
  • Walang limitasyong trapiko

Ang taripa ay napapailalim sa mga karagdagang teknikal na paghihigpit, mga detalye sa pahina ang aming cool na alok - VPS para sa 30 rubles. 

Para kanino angkop ang virtual server na ito? Oo, sa halos lahat: mga nagsisimula, mahilig, makaranasang developer, DIY fan, at kahit ilang kumpanya.

Para saan ang VPS na ito?

Sa tingin namin, ang mga mambabasa ni Habr ay tiyak na makakahanap ng kanilang sariling paraan ng paggamit ng pagsasaayos na ito, ngunit nagpasya kaming kolektahin ang aming sariling pagpili ng mga ideya - paano kung may nangangailangan nito, ngunit hindi alam ng mga lalaki?

  • Ilagay ang iyong simpleng website, portfolio, resume na may code, atbp. Siyempre, ang iyong sariling dinisenyo na website ay gumagawa ng isang positibong impression sa employer. Ilagay ito sa iyong VPS at maging responsable para sa seguridad at katatagan ng site mismo, at hindi ng mga tauhan ng mga regular na provider ng pagho-host.
  • Gumamit ng VPS para sa mga layuning pang-edukasyon: i-host ang iyong proyekto, pag-aralan ang mga tampok ng server at operating system ng server, mag-eksperimento sa DNS, mag-tinker sa isang maliit na site na pang-edukasyon.
  • Para sa telephony. Minsan ang isang indibidwal na negosyante, freelancer o isang napakaliit na kumpanya ay lubhang nangangailangan ng IP telephony, at ang mga operator ng mismong telephony na ito ay napaka-gahaman. Simple lang: kinukuha namin ang aming server, bumili ng numero mula sa operator ng IP telephony, nag-set up ng virtual na PBX at lumikha ng mga internal na numero (kung kinakailangan). Napakalaki ng ipon.
  • Gamitin ang server upang subukan ang iyong mga application.
  • Gamitin ang server para sa mga eksperimento sa DIY, kabilang ang pagkontrol at pagkolekta ng data mula sa mga sensor ng smart home system.
  • Ang isang hindi pangkaraniwang paraan upang gamitin ito ay ang paglalagay ng virtual exchange trading assistant, isang trading robot, sa server. Ikaw ay magiging ganap na responsable para sa katatagan at seguridad ng server, na nangangahulugang makakatanggap ka ng isang kinokontrol na instrumento para sa pangangalakal sa mga stock market. Well, kung sakaling may interesado o nagpaplano :)

Mayroong mga aplikasyon para sa naturang VPS sa corporate sphere. Bilang karagdagan sa nabanggit na serbisyo ng telepono, maaari mong ipatupad ang ilang mga kagiliw-giliw na bagay. Halimbawa:

  • Maglagay ng maliliit na database at impormasyon na maa-access ng mga naglalakbay na empleyado sa malayo, halimbawa, gamit ang ftp. Ito ay magbibigay-daan sa iyo upang mabilis na makipagpalitan ng mga bagong analytics, na-update na mga configuration para sa mga taong nagbebenta, mga presentasyon, atbp.
  • Magbigay ng pansamantalang access sa mga user o kliyente upang ipakita ang software o media.

VPS test drive para sa 30 rubles - tapos na para sa iyo

Ang 30 rubles ay napakaliit na hindi mo nais na kumuha ng isang card upang magbayad at subukan. Kami rin minsan ay tamad, ngunit sa pagkakataong ito ginawa namin ang lahat para sa iyo. Bago ilunsad ang mga server sa labanan, nagsagawa kami ng pagsubok upang suriin ang lahat ng mga detalye at ipakita kung ano ang kaya ng mga server sa taripa na ito. Upang gawin itong mas kawili-wili, nagdagdag kami ng matinding at sinuri kung paano kikilos ang pagsasaayos na ito kung ang density at load ay lumampas sa mga halagang itinakda namin. 

Ang host ay nasa ilalim ng pagkarga ng isang bilang ng mga virtual machine na nagsagawa ng iba't ibang mga gawain sa processor at aktibong ginamit ang disk subsystem. Ang layunin ay upang gayahin ang isang mataas na density ng pagkakalagay at isang load na maihahambing sa o mas malaki kaysa sa isang labanan.

Bilang karagdagan sa patuloy na pag-load, nag-install kami ng 3 virtual machine na nangongolekta ng mga synthetic na sukatan gamit ang sysbench, ang average na mga resulta ay ibinigay sa ibaba, at 50 virtual machine na lumikha ng karagdagang pag-load. Ang lahat ng mga pagsubok na virtual machine ay may parehong configuration (1 core, RAM 512 GB, SSD 10 GB), ang karaniwang debian 9.6 na imahe ay napili bilang operating system, na inaalok sa mga user sa RUVDS.

Ang pagkarga ay ginaya sa kalikasan at magnitude na maihahambing sa labanan:

  • Ang ilang mga virtual machine ay inilunsad na may mababang load
  • Ang ilang mga makina ay nagpatakbo ng isang test script na ginagaya ang pagkarga sa processor (gamit ang utility diin)
  • Sa natitirang bahagi ng mga virtual machine, nagpatakbo kami ng script na gumamit ng dd upang kopyahin ang data mula sa pre-prepared na data patungo sa disk na may limitasyong nakatakda gamit ang pv (makikita ang mga halimbawa dito ΠΈ dito).

Gayundin, gaya ng naaalala mo, mayroon kaming tatlong makina na nangolekta ng mga sintetikong sukatan.

Sa bawat makina, ang isang script ay ipinapatupad nang paikot bawat 15 minuto, na nagpapatakbo ng mga karaniwang pagsubok sa sysbench para sa processor, memorya at disk.

Script sysbench.sh

#!/bin/bash
date +"%Y-%m-%d %H:%M:%S" >> /root/sysbench/results.txt
sysbench --test=cpu run >> /root/sysbench/results.txt
sysbench --test=memory run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqwr run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=seqrd run >> /root/sysbench/results.txt
sysbench --test=fileio --file-test-mode=rndrw run >> /root/sysbench/results.txt

Ang mga resulta ay ipinakita para sa kaginhawahan sa sysbench na format, ngunit ang mga average na halaga para sa buong panahon ng pagsubok ay kinuha mula sa lahat ng mga makina, ang resulta ay makikita dito:

Sysbanch-avg.txtsysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing CPU performance benchmark

Threads started!
Done.

Maximum prime number checked in CPU test: 10000

Test execution summary:
total time: 19.2244s
total number of events: 10000
total time taken by event execution: 19.2104
per-request statistics:
min: 1.43ms
avg: 1.92ms
max: 47.00ms
approx. 95 percentile: 3.02ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 19.2104/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Doing memory operations speed test
Memory block size: 1K

Memory transfer size: 102400M

Memory operations type: write
Memory scope type: global
Threads started!
Done.

Operations performed: 104857600 (328001.79 ops/sec)

102400.00 MB transferred (320.32 MB/sec)

Test execution summary:
total time: 320.9155s
total number of events: 104857600
total time taken by event execution: 244.8399
per-request statistics:
min: 0.00ms
avg: 0.00ms
max: 139.41ms
approx. 95 percentile: 0.00ms

Threads fairness:
events (avg/stddev): 104857600.0000/0.00
execution time (avg/stddev): 244.8399/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential write (creation) test
Threads started!
Done.

Operations performed: 0 Read, 131072 Write, 128 Other = 131200 Total
Read 0b Written 2Gb Total transferred 2Gb (320.1Mb/sec)
20251.32 Requests/sec executed

Test execution summary:
total time: 6.9972s
total number of events: 131072
total time taken by event execution: 5.2246
per-request statistics:
min: 0.01ms
avg: 0.04ms
max: 96.76ms
approx. 95 percentile: 0.03ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 5.2246/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing sequential read test
Threads started!
Done.

Operations performed: 131072 Read, 0 Write, 0 Other = 131072 Total
Read 2Gb Written 0b Total transferred 2Gb (91.32Mb/sec)
5844.8 Requests/sec executed

Test execution summary:
total time: 23.1054s
total number of events: 131072
total time taken by event execution: 22.9933
per-request statistics:
min: 0.00ms
avg: 0.18ms
max: 295.75ms
approx. 95 percentile: 0.77ms

Threads fairness:
events (avg/stddev): 131072.0000/0.00
execution time (avg/stddev): 22.9933/0.00

sysbench 0.4.12: multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1

Extra file open flags: 0
128 files, 16Mb each
2Gb total file size
Block size 16Kb
Number of random requests for random IO: 10000
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Threads started!
Done.

Operations performed: 6000 Read, 4000 Write, 12800 Other = 22800 Total
Read 93.75Mb Written 62.5Mb Total transferred 156.25Mb (1341.5Kb/sec)
85.61 Requests/sec executed

Test execution summary:
total time: 152.9786s
total number of events: 10000
total time taken by event execution: 14.1879
per-request statistics:
min: 0.01ms
avg: 1.41ms
max: 210.22ms
approx. 95 percentile: 4.95ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 14.1879/0.00

Ang mga resulta ay nagpapahiwatig, ngunit hindi pa rin dapat kunin bilang QoS. 

Mga makina na lumilikha ng karagdagang pagkarga

Software:

  • apt-makakuha ng update
  • apt-get upgrade
  • apt-get install python-pip
  • pip install mysql-connector-python-rf

Naka-install na MariaDB, Paano dito:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- Π½ΡƒΠΆΠ½ΠΎ для test_employees_sha

Kinuha ang test base kaya:

Ang database ay na-deploy tulad ng tinukoy dito:

mysql -t < employees.sql
mysql -t < test_employees_sha.sql

Maliit na base ng pagsubok:

mesa 

RowsCount 

Laki ng data (MB)

Laki ng index (KB)

kagawaran 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

dept_manager 

24 

0.02

16.00

empleyado 

299379 

14.52

0.00

suweldo 

2838426 

95.63

0.00 

pamagat 

442783 

19.56

0.00

Ang isang primitive na serbisyo sa pagsubok ay nakasulat sa tuhod sa Python; ito ay nagsasagawa ng apat na operasyon:

  1. getState: ibinabalik ang status
  2. getEmployee: nagbabalik ng mga empleyado (+suweldo, +title) mula sa database
  3. patchEmployee: nagbabago ng mga field ng empleyado
  4. insertSalary: nagsingit ng suweldo

Pinagmulan ng serbisyo (dbtest.py)

#!/usr/bin/python
import mysql.connector as mariadb
from flask import Flask, json, request, abort
from mysql.connector.constants import ClientFlag

app = Flask(__name__)

def getFields(cursor):
    results = {}
    column = 0
    for d in cursor.description:
        results[d[0]] = column
        column = column + 1
    return results

PAGE_SIZE = 30

@app.route("/")
def main():
    return "Hello!"

@app.route("/employees/<page>", methods=['GET'])
def getEmployees(page):
    offset = (int(page) - 1) * PAGE_SIZE
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees LIMIT {} OFFSET {}".format(PAGE_SIZE, offset))
    return {'employees': [i[0] for i in cursor.fetchall()]}

@app.route("/employee/<id>", methods=['GET'])
def getEmployee(id):
    id = int(id)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees')
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM employees WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    employee = {}
    found = False
    for row in cursor.fetchall():
        found = True
        employee = {
            "birth_date": row[fields["birth_date"]],
            "first_name": row[fields["first_name"]],
            "last_name": row[fields["last_name"]],
            "gender": row[fields["gender"]],
            "hire_date": row[fields["hire_date"]]
        }
    if not found:
        abort(404)
    cursor.execute("SELECT * FROM salaries WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    salaries = []
    for row in cursor.fetchall():
        salary = {
            "salary": row[fields["salary"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        salaries.append(salary)
    employee["salaries"] = salaries
    cursor.execute("SELECT * FROM titles WHERE emp_no = {}".format(id))
    fields = getFields(cursor)
    titles = []
    for row in cursor.fetchall():
        title = {
            "title": row[fields["title"]],
            "from_date": row[fields["from_date"]],
            "to_date": row[fields["to_date"]]
        }
        titles.append(title)
    employee["titles"] = titles
    return json.dumps({
        "status": "success",
        "employee": employee
    })

def isFieldValid(t, v):
    if t == "employee":
        return v in ["birdth_date", "first_name", "last_name", "hire_date"]
    else:
        return false

@app.route("/employee/<id>", methods=['PATCH'])
def setEmployee(id):
    id = int(id)
    content = request.json
    print(content)
    setList = ""
    data = []
    for k, v in content.iteritems():
        if not isFieldValid("employee", k):
            continue
        if setList != "":
            setList = setList + ", "
        setList = setList + k + "=%s"
        data.append(v)
    data.append(id)
    print(setList)
    print(data)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    cursor.execute("UPDATE employees SET {} WHERE emp_no = %s".format(setList), data)
    connection.commit()
    if cursor.rowcount < 1:
        abort(404)
    return json.dumps({
        "status": "success"
    })

@app.route("/salary", methods=['PUT'])
def putSalary():
    content = request.json
    print(content)
    connection = mariadb.connect(user='admin', password='q5XpRomdSr', database='employees', client_flags=[ClientFlag.FOUND_ROWS])
    cursor = connection.cursor()
    data = [content["emp_no"], content["salary"], content["from_date"], content["to_date"]]
    cursor.execute("INSERT INTO salaries (emp_no, salary, from_date, to_date) VALUES (%s, %s, %s, %s)", data)
    connection.commit()
    return json.dumps({
        "status": "success"
    })


@app.route("/state", methods=['GET'])
def getState():
    return json.dumps({
        "status": "success",
        "state": "working"
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0',port='5002')

Warning! Sa anumang pagkakataon dapat gawin ang serbisyong ito bilang isang halimbawa o gabay!

Isinasagawa ang mga pagsusulit gamit ang magandang lumang JMeter. Ang isang serye ng mga pagsubok ay inilunsad na tumatagal mula 15 minuto hanggang 2 oras, nang walang mga pagkaantala, ang porsyento ng mga kahilingan ay nagbago, ang throughput ay nag-iiba mula 300 hanggang 600 na mga kahilingan kada minuto. Bilang ng mga thread mula 50 hanggang 500.

Dahil sa ang katunayan na ang database ay napakaliit, ang utos:

mysql -e "SHOW ENGINE INNODB STATUS"

Ipinapakita na:

Buffer pool hit rate 923 / 1000, young-making rate 29 / 1000 not 32 / 1000

Nasa ibaba ang average na oras ng pagtugon para sa mga kahilingan:

Tatak

karaniwan

panggitna

90%Linya

95%Linya

99%Linya

Min

Max

makakuha ng Empleyado

37.64

12.57

62.28

128.5

497.57

5

4151.78

getState

17

7.57

30.14

58.71

193

3

2814.71

patchEmpleyado

161.42

83.29

308

492.57

1845.14

5

6639.4

ilagaySweldo

167.21

86.93

315.34

501.07

1927.12

7

6722.44

Maaaring mahirap para sa iyo na husgahan mula sa mga sintetikong resultang ito kung gaano kaakma ang VPS na ito para sa iyong mga partikular na gawain, at sa pangkalahatan, ang mga nakalistang pamamaraan ay limitado sa mga kasong iyon na kailangan naming harapin sa isang anyo o iba pa. Kaya ang aming listahan ay malinaw na hindi kumpleto. Inaanyayahan ka naming gumuhit ng iyong sariling mga konklusyon at subukan ang server para sa 30 rubles sa iyong mga tunay na aplikasyon at gawain at iminumungkahi ang iyong mga pagpipilian para sa pagsasaayos na ito sa mga komento.

Pinagmulan: www.habr.com

Magdagdag ng komento