Ni nzuri sana wakati vitu vidogo vyote viko karibu: kalamu nzuri na daftari, penseli iliyoinuliwa, panya ya starehe, waya kadhaa za ziada, nk. Mambo haya yasiyoonekana hayavutii, lakini huongeza faraja kwa maisha. Hadithi sawa ni pamoja na maombi mbalimbali ya simu na kompyuta ya mezani: kwa viwambo vya muda mrefu, kwa kupunguza ukubwa wa picha, kwa kuhesabu fedha za kibinafsi, kamusi, watafsiri, waongofu, nk. Je! unayo? VPS - ambayo ni ya bei nafuu, iko karibu kila wakati na huleta faida nyingi? Hapana, sio ile uliyo nayo katika kampuni yako, lakini yako mwenyewe, "mfukoni" moja. Tulidhani kwamba bila VPS ndogo mnamo 2019 ilikuwa ya kusikitisha kwa njia fulani, kama vile bila kalamu ya kawaida ya chemchemi kwenye hotuba. Kwa nini uwe na huzuni? Ni majira ya joto. Vipi majira ya joto? Majira ya joto kwa mtaalamu wa IT: kukaa nyumbani, kufanya kazi kwenye miradi yako favorite bila majuto yoyote. Kwa ujumla, tulifikiri na kuifanya.
Ukomunisti umefika, wandugu.
Yeye ni kama hivyo - VPS yetu kwa thelathini
Tumesoma makala nyingi kutoka kwa washindani na watumiaji ambao waliandika miaka 3-4 iliyopita kuhusu kwa nini VPS ya gharama nafuu haihitajiki. Kweli, hiyo ni kweli, basi VPS "kwa senti" ilikuwa uuzaji safi na haikuweza kutoa fursa za kawaida za kufanya kazi. Lakini nyakati zinabadilika, gharama ya rasilimali halisi inakuwa chini na chini, na kwa rubles 30 kwa mwezi tuko tayari kutoa hii:
Kichakataji: Intel Xeon 2 GHz (msingi 1)
Mfumo wa Linux (Debian, Ubuntu, CentOS kuchagua kutoka)
Anwani 1 maalum ya IPv4
GB 10 ya hifadhi ya data kwenye hifadhi za SSD za kiwango cha biashara haraka
RAM: 512 MB
Kwa bili ya pili
Trafiki isiyo na kikomo
Ushuru unakabiliwa na vikwazo vya ziada vya kiufundi, maelezo juu ukurasa toleo letu la baridi - VPS kwa rubles 30.
Je, seva hii pepe inafaa kwa ajili ya nani? Ndio kwa karibu kila mtu: wanaoanza, wanaopenda, watengenezaji wenye uzoefu, mashabiki wa DIY na hata kampuni zingine.
VPS hii inafaa kwa nini?
Tunafikiria kwamba wasomaji wa Habr watapata njia yao wenyewe ya kutumia usanidi huu, lakini tuliamua kukusanya maoni yetu wenyewe - vipi ikiwa mtu anahitaji, lakini wanaume hawajui?
Weka tovuti yako rahisi, kwingineko, endelea na msimbo, nk. Bila shaka, tovuti yako mwenyewe iliyoundwa hufanya hisia chanya kwa mwajiri. Weka kwenye VPS yako na uwajibike kwa usalama na utulivu wa tovuti mwenyewe, na si kwa wafanyakazi wa watoa huduma wa kawaida wa kukaribisha.
Tumia VPS kwa madhumuni ya kielimu: mwenyeji wa mradi wako, soma sifa za seva na mfumo wa uendeshaji wa seva, jaribu DNS, cheza na tovuti ndogo ya elimu.
Kwa simu. Wakati mwingine mjasiriamali binafsi, mfanyakazi huru au kampuni ndogo sana huhitaji sana simu ya IP, na waendeshaji wa simu hii ni wachoyo sana. Ni rahisi: tunachukua seva yetu, kununua nambari kutoka kwa operator wa simu ya IP, kuanzisha PBX ya kawaida na kuunda nambari za ndani (ikiwa ni lazima). Akiba ni kubwa sana.
Tumia seva kujaribu programu zako.
Tumia seva kwa majaribio ya DIY, ikiwa ni pamoja na kudhibiti na kukusanya data kutoka kwa vitambuzi mahiri vya mfumo wa nyumbani.
Njia isiyo ya kawaida ya kuitumia ni kuweka msaidizi wa biashara ya kubadilishana mtandaoni, roboti ya biashara, kwenye seva. Utawajibika kikamilifu kwa uthabiti na usalama wa seva, ambayo ina maana kwamba utapokea chombo kinachodhibitiwa cha kufanya biashara kwenye masoko ya hisa. Kweli, ikiwa mtu yeyote ana nia au kupanga :)
Kuna maombi ya VPS kama hii katika nyanja ya ushirika. Mbali na huduma ya simu iliyotajwa tayari, unaweza kutekeleza mambo kadhaa ya kuvutia. Kwa mfano:
Weka hifadhidata ndogo na habari ambazo zitapatikana kwa wafanyikazi wanaosafiri kwa mbali, kwa mfano, kwa kutumia ftp. Hii itakuruhusu kubadilishana haraka sana uchanganuzi mpya, usanidi uliosasishwa kwa watu wa mauzo, mawasilisho, n.k.
Wape watumiaji au wateja ufikiaji wa muda mfupi ili kuonyesha programu au media.
VPS mtihani gari kwa rubles 30 - kufanyika kwa ajili yenu
Rubles 30 ni kidogo sana kwamba hutaki hata kuchukua kadi ya kulipa na kupima. Wakati mwingine sisi ni wavivu sana, lakini wakati huu tulifanya kila kitu kwa ajili yako. Kabla ya kuzindua seva vitani, tulifanya jaribio ili kuangalia maelezo yote na kuonyesha ni nini seva zinaweza kufanya kwa ushuru huu. Ili kuifanya ipendeze zaidi, tuliongeza uliokithiri na kuangalia jinsi usanidi huu ungefanya ikiwa msongamano na mzigo ulizidi maadili tuliyoweka.
Mpangishi alikuwa chini ya mzigo wa idadi ya mashine pepe ambazo zilifanya kazi mbalimbali kwenye kichakataji na kutumia kikamilifu mfumo mdogo wa diski. Lengo ni kuiga msongamano mkubwa wa uwekaji na mzigo unaolinganishwa na au mkubwa zaidi kuliko ule wa mapigano.
Kando na upakiaji wa kila mara, tulisakinisha mashine 3 pepe ambazo zilikusanya vipimo vya sintetiki kwa kutumia sysbench, matokeo ya wastani ambayo yalitolewa hapa chini, na mashine 50 pepe zilizounda mzigo wa ziada. Mashine zote pepe za majaribio zilikuwa na usanidi sawa (msingi 1, RAM 512 GB, SSD 10 GB), picha ya kawaida ya debian 9.6 ilichaguliwa kama mfumo wa uendeshaji, ambayo hutolewa kwa watumiaji kwenye RUVDS.
Mzigo uliigwa kwa asili na ukubwa kulinganishwa na mapigano:
Baadhi ya mashine pepe zilizinduliwa zikiwa na mzigo mdogo
Mashine zingine ziliendesha hati ya jaribio inayoiga mzigo kwenye kichakataji (kwa kutumia matumizi mkazo)
Kwenye sehemu iliyobaki ya mashine pepe, tuliendesha hati iliyotumia dd kunakili data kutoka kwa data iliyotayarishwa awali hadi kwenye diski na kikomo kilichowekwa kwa kutumia pv (mifano inaweza kuonekana hapa ΠΈ hapa).
Pia, kama unavyokumbuka, tulikuwa na mashine tatu zilizokusanya vipimo vya sintetiki.
Kwenye kila mashine, hati ilitekelezwa kwa mzunguko kila baada ya dakika 15, ambayo huendesha majaribio ya kawaida ya sysbench kwa kichakataji, kumbukumbu na diski.
Hati 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
Matokeo yanawasilishwa kwa urahisi katika muundo wa sysbench, lakini maadili ya wastani ya kipindi chote cha majaribio yalichukuliwa kutoka kwa mashine zote, matokeo yanaweza kuonekana hapa:
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
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
Matokeo ni dalili, lakini bado hayapaswi kuchukuliwa kama QoS.
mysql -t < employees.sql
mysql -t < test_employees_sha.sql
Msingi wa jaribio la ujazo mdogo:
Meza
RowsCount
Ukubwa wa data (MB)
Ukubwa wa faharasa (KB)
idara
9
0.02
16.00
dept_emp
331143
11.52
5648.00
meneja_wa_dept
24
0.02
16.00
wafanyakazi
299379
14.52
0.00
mishahara
2838426
95.63
0.00
majina
442783
19.56
0.00
Huduma ya mtihani wa awali imeandikwa kwenye goti huko Python; hufanya shughuli nne:
getState: inarudisha hali
getEmployee: hurejesha wafanyakazi (+mishahara, +vyeo) kutoka kwa hifadhidata
kirakaMfanyakazi: hubadilisha nyanja za wafanyikazi
kuingizaMshahara: kuingiza mshahara
Chanzo cha huduma (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')
Attention! Kwa hali yoyote ile huduma hii isichukuliwe kama mfano au mwongozo!
Vipimo hufanywa kwa kutumia JMeter nzuri ya zamani. Msururu wa majaribio ya kuanzia dakika 15 hadi saa 2 ulizinduliwa, bila kukatizwa, asilimia ya maombi ilitofautiana, na matokeo yalitofautiana kutoka maombi 300 hadi 600 kwa dakika. Idadi ya nyuzi kutoka 50 hadi 500.
Kwa sababu ya ukweli kwamba hifadhidata ni ndogo sana, amri:
mysql -e "SHOW ENGINE INNODB STATUS"
Inaonyesha kuwa:
Buffer pool hit rate 923 / 1000, young-making rate 29 / 1000 not 32 / 1000
Zifuatazo ni nyakati za wastani za kujibu maombi:
Chapa
wastani
Kati
90%Mstari
95%Mstari
99%Mstari
Min
Max
pata Mfanyakazi
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
kirakaMfanyakazi
161.42
83.29
308
492.57
1845.14
5
6639.4
wekaMshahara
167.21
86.93
315.34
501.07
1927.12
7
6722.44
Inaweza kuwa vigumu kwako kuhukumu kutokana na matokeo haya ya syntetisk jinsi VPS hii inavyofaa kwa kazi zako maalum na, kwa ujumla, mbinu zilizoorodheshwa ni mdogo kwa kesi hizo ambazo tulipaswa kushughulikia kwa namna moja au nyingine. wazi sio kamili. Tunakualika ufanye hitimisho lako mwenyewe na ujaribu seva kwa rubles 30 kwenye programu na kazi zako halisi na upendekeze chaguzi zako za usanidi huu kwenye maoni.