Brain + VPS برای 30 روبل =؟

وقتی همه چیزهای کوچک ضروری در دسترس هستند بسیار خوب است: یک خودکار و دفترچه یادداشت خوب، یک مداد تیز، یک ماوس راحت، چند سیم اضافی و غیره. این چیزهای نامحسوس جلب توجه نمی کنند، اما به زندگی آرامش می بخشند. همین داستان در مورد برنامه های مختلف موبایل و دسکتاپ وجود دارد: برای اسکرین شات های طولانی، برای کاهش اندازه یک عکس، برای محاسبه مالی شخصی، فرهنگ لغت، مترجم، مبدل و غیره. آیا شما یکی دارید؟ VPS - کدام ارزان است، همیشه در دسترس است و مزایای زیادی به همراه دارد؟ نه، نه شرکتی که در شرکت خود دارید، بلکه یکی از شرکت‌های خودتان است. ما فکر می کردیم که بدون VPS کوچک در سال 2019 به نوعی غم انگیز بود، درست مانند بدون قلم معمولی در یک سخنرانی. چرا غمگین باشیم؟ تابستان است. تابستان چطور است؟ تابستان برای متخصص فناوری اطلاعات: نشستن در خانه، بدون هیچ پشیمانی روی پروژه های مورد علاقه خود کار کنید. در کل فکر کردیم و انجامش دادیم.

Brain + VPS برای 30 روبل =؟
رفقا، کمونیسم رسید.

او همینطور است - VPS ما برای سی

ما مقالات زیادی از رقبا و کاربرانی که 3-4 سال پیش در مورد اینکه چرا به یک VPS ارزان نیاز نیست، نوشته اند، خوانده ایم. خوب، درست است، پس VPS "برای یک پنی" بازاریابی خالص بود و نمی توانست فرصت های کاری عادی را ارائه دهد. اما زمان در حال تغییر است، هزینه منابع مجازی کمتر و کمتر می شود و برای 30 روبل در ماه ما آماده ارائه این هستیم:

  • پردازنده: Intel Xeon 2 گیگاهرتز (1 هسته)
  • سیستم لینوکس (دبیان، اوبونتو، CentOS برای انتخاب)
  • 1 آدرس IPv4 اختصاصی
  • 10 گیگابایت حافظه ذخیره سازی اطلاعات در درایوهای SSD سریع کلاس سازمانی
  • رم: 512 مگابایت
  • صورتحساب در ثانیه
  • ترافیک نامحدود

تعرفه مشمول محدودیت‌های فنی اضافی، جزئیات بیشتر است صفحه پیشنهاد جالب ما - VPS برای 30 روبل. 

این سرور مجازی برای چه کسانی مناسب است؟ تقریباً برای همه بله: مبتدیان، علاقه مندان، توسعه دهندگان با تجربه، طرفداران DIY و حتی برخی از شرکت ها.

این VPS برای چه کاری مناسب است؟

ما فکر می‌کنیم که خوانندگان Habr قطعاً راه خود را برای استفاده از این پیکربندی پیدا خواهند کرد، اما تصمیم گرفتیم ایده‌های خود را جمع‌آوری کنیم - اگر کسی به آن نیاز داشته باشد، اما مردان ندانند، چه؟

  • وب سایت ساده، نمونه کارها، رزومه خود را با کد و غیره قرار دهید. مطمئناً وب سایت طراحی شده شما تأثیر مثبتی بر کارفرما می گذارد. آن را روی VPS خود قرار دهید و مسئولیت امنیت و ثبات سایت را خودتان بر عهده بگیرید و نه توسط کارکنان ارائه دهندگان هاست معمولی.
  • از VPS برای اهداف آموزشی استفاده کنید: پروژه خود را میزبانی کنید، ویژگی های سرور و سیستم عامل سرور را مطالعه کنید، با DNS آزمایش کنید، با یک سایت آموزشی کوچک سرهم کنید.
  • برای تلفن. گاهی اوقات یک کارآفرین انفرادی، فریلنسر یا یک شرکت بسیار کوچک به شدت به تلفن IP نیاز دارد و اپراتورهای این تلفن بسیار حریص هستند. ساده است: ما سرور خود را می گیریم، یک شماره از یک اپراتور تلفن IP می خریم، یک PBX مجازی راه اندازی می کنیم و شماره های داخلی ایجاد می کنیم (در صورت لزوم). پس انداز عظیم است.
  • از سرور برای آزمایش برنامه های خود استفاده کنید.
  • از سرور برای آزمایش‌های DIY، از جمله کنترل و جمع‌آوری داده‌ها از سنسورهای سیستم خانه هوشمند استفاده کنید.
  • یک راه غیرمعمول برای استفاده از آن، قرار دادن یک دستیار تجارت صرافی مجازی، یک ربات معامله گر، روی سرور است. شما مسئولیت کامل ثبات و امنیت سرور را بر عهده خواهید داشت، به این معنی که ابزار کنترل شده ای برای معامله در بازارهای سهام دریافت خواهید کرد. خوب، اگر کسی علاقه مند است یا برنامه ریزی می کند :)

برنامه های کاربردی برای چنین VPS در حوزه شرکت وجود دارد. علاوه بر خدمات تلفنی که قبلا ذکر شد، می توانید چندین چیز جالب را پیاده سازی کنید. مثلا:

  • پایگاه داده ها و اطلاعات کوچکی را قرار دهید که برای کارمندان مسافرتی از راه دور قابل دسترسی باشد، به عنوان مثال، با استفاده از ftp. این به شما امکان می دهد خیلی سریع تجزیه و تحلیل های تازه، تنظیمات به روز شده برای فروشندگان، ارائه ها و غیره را مبادله کنید.
  • به کاربران یا مشتریان برای نمایش نرم افزار یا رسانه دسترسی موقت بدهید.

درایو تست VPS برای 30 روبل - برای شما انجام شده است

30 روبل آنقدر کم است که حتی نمی خواهید کارتی برای پرداخت و آزمایش بردارید. ما هم گاهی خیلی تنبل هستیم، اما این بار همه چیز را برای شما انجام دادیم. قبل از راه‌اندازی سرورها به نبرد، آزمایشی را انجام دادیم تا تمام جزئیات را بررسی کنیم و نشان دهیم که سرورها در این تعرفه چه توانایی‌هایی دارند. برای جالب‌تر کردن آن، افراطی را اضافه کردیم و بررسی کردیم که اگر چگالی و بار از مقادیری که ما تنظیم کرده‌ایم بیشتر شود، این پیکربندی چگونه عمل می‌کند. 

میزبان زیر بار تعدادی ماشین مجازی بود که وظایف مختلفی را روی پردازنده انجام می دادند و به طور فعال از زیر سیستم دیسک استفاده می کردند. هدف شبیه سازی چگالی بالای قرارگیری و باری قابل مقایسه یا بزرگتر از یک بار جنگی است.

علاوه بر بار ثابت، 3 ماشین مجازی نصب کردیم که معیارهای مصنوعی را با استفاده از sysbench جمع‌آوری می‌کردند که میانگین نتایج آن در زیر آورده شده است و 50 ماشین مجازی که بار اضافی ایجاد کردند. تمامی ماشین‌های مجازی آزمایشی پیکربندی یکسانی داشتند (1 هسته، رم 512 گیگابایت، SSD 10 گیگابایت)، تصویر استاندارد debian 9.6 به عنوان سیستم عامل انتخاب شد که در RUVDS به کاربران ارائه می‌شود.

بار در ماهیت و بزرگی قابل مقایسه با جنگ شبیه سازی شد:

  • برخی از ماشین های مجازی با بار کم راه اندازی شدند
  • برخی از ماشین‌ها یک اسکریپت آزمایشی را اجرا کردند که بار روی پردازنده را شبیه‌سازی می‌کرد (با استفاده از ابزار فشار)
  • در قسمت باقی مانده از ماشین های مجازی، ما اسکریپتی را اجرا کردیم که از dd برای کپی داده ها از داده های از پیش آماده شده به دیسک با یک مجموعه محدود با استفاده از pv استفاده می کرد (نمونه هایی را می توان مشاهده کرد. اینجا и اینجا).

همچنین، همانطور که به یاد دارید، ما سه دستگاه داشتیم که معیارهای مصنوعی را جمع آوری می کردند.

در هر دستگاه، یک اسکریپت به صورت چرخه‌ای هر 15 دقیقه اجرا می‌شد که تست‌های استاندارد sysbench را برای پردازنده، حافظه و دیسک اجرا می‌کرد.

اسکریپت 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

نتایج برای راحتی در قالب sysbench ارائه شده است، اما مقادیر متوسط ​​برای کل دوره آزمایش از همه ماشین ها گرفته شده است، نتیجه را می توان در اینجا مشاهده کرد:

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

نتایج نشان دهنده هستند، اما هنوز نباید به عنوان QoS در نظر گرفته شوند. 

ماشین هایی که بار اضافی ایجاد می کنند

نرم افزار:

  • با apt-get برای بروز رسانی
  • apt-get ارتقا دهید
  • apt-get نصب python-pip
  • پیپ نصب mysql-connector-python-rf

نصب شده MariaDB، How to اینجا:

apt-get install libmariadbclient-dev
mysql -e "INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so';" -- нужно для test_employees_sha

پایه آزمون گرفته شد از این رو:

پایگاه داده همانطور که مشخص شده است مستقر می شود اینجا:

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

پایه آزمون کوچک:

جدول 

تعداد ردیف 

حجم داده ها (MB)

اندازه فهرست (KB)

گروه ها 

9

0.02

16.00

dept_emp 

331143 

11.52

5648.00

dept_manager 

24 

0.02

16.00

کارکنان 

299379 

14.52

0.00

حقوق 

2838426 

95.63

0.00 

عناوین 

442783 

19.56

0.00

یک سرویس تست اولیه در پایتون روی زانو نوشته شده است؛ این سرویس چهار عمل را انجام می دهد:

  1. getState: وضعیت را برمی‌گرداند
  2. getEmployee: کارمندان (+حقوق، +عناوین) را از پایگاه داده برمی گرداند
  3. patchEmployee: فیلدهای کارمند را تغییر می دهد
  4. insertSalary: درج حقوق

منبع خدمات (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')

اخطار! تحت هیچ شرایطی نباید این سرویس را به عنوان مثال یا راهنما در نظر گرفت!

آزمایش ها با استفاده از JMeter خوب قدیمی انجام می شود. یک سری آزمایش از 15 دقیقه تا 2 ساعت راه اندازی شد، بدون وقفه، درصد درخواست ها متفاوت بود و توان عملیاتی آن از 300 تا 600 درخواست در دقیقه متغیر بود. تعداد نخ ها از 50 تا 500.

با توجه به اینکه پایگاه داده بسیار کوچک است، دستور:

mysql -e "SHOW ENGINE INNODB STATUS"

نشان میدهد که:

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

در زیر میانگین زمان پاسخگویی به درخواست ها آمده است:

برچسب

میانگین

متوسط

90% خط

95% خط

99% خط

حداقل

حداکثر

getEmployee

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

patchEmployee

161.42

83.29

308

492.57

1845.14

5

6639.4

قرار دادن حقوق

167.21

86.93

315.34

501.07

1927.12

7

6722.44

ممکن است برای شما دشوار باشد که از روی این نتایج مصنوعی قضاوت کنید که این VPS چقدر برای وظایف خاص شما مناسب است و به طور کلی، روش های ذکر شده محدود به مواردی است که ما مجبور بودیم به یک شکل با آنها برخورد کنیم. بنابراین لیست ما این است. واضح است که جامع نیست ما از شما دعوت می کنیم نتیجه گیری خود را انجام دهید و سرور را با 30 روبل در برنامه ها و وظایف واقعی خود آزمایش کنید و گزینه های خود را برای این پیکربندی در نظرات پیشنهاد دهید.

منبع: www.habr.com

اضافه کردن نظر