python যবহ কিভাবে আপনি উইন্ডোজ একটি সেবা হিসাবে একটি পাইথন স্ক্রিপ্ট চালানো?




বাংলায় পাইথন (8)

আমি প্রোগ্রামগুলির একটি সেটের জন্য আর্কিটেকচারের স্কেচ করছি যা ডাটাবেসের মধ্যে সংরক্ষিত বিভিন্ন আন্তঃসংযোগ বস্তু ভাগ করে। আমি চাই যে প্রোগ্রামগুলি একটি এমন পরিষেবা হিসাবে কাজ করবে যা এই বস্তুর ক্রিয়াকলাপগুলির জন্য উচ্চ স্তরের ইন্টারফেস সরবরাহ করে এবং অন্যান্য প্রোগ্রামগুলি সেই পরিষেবাটির মাধ্যমে বস্তুগুলি অ্যাক্সেস করতে পারে।

আমি বর্তমানে Python এবং Django ফ্রেমওয়ার্কের জন্য সেই প্রযুক্তি বাস্তবায়নের প্রযুক্তি হিসাবে লক্ষ্য করছি। আমি নিশ্চিত যে লিনাক্সে পাইথন প্রোগ্রামকে কিভাবে ডিনামাইজ করবো তা আমি নিশ্চিত। যাইহোক, এটি একটি ঐচ্ছিক স্পেক আইটেম যা সিস্টেমটি উইন্ডোজকে সমর্থন করবে। আমার উইন্ডোজ প্রোগ্রামিং এর সাথে সামান্য অভিজ্ঞতা আছে এবং উইন্ডোজ পরিষেবাদিতে কোন অভিজ্ঞতা নেই।

উইন্ডোজ পরিষেবাদি হিসাবে একটি পাইথন প্রোগ্রাম চালানো কি সম্ভব (অর্থাৎ ব্যবহারকারী লগইন ছাড়া স্বয়ংক্রিয়ভাবে চালানো)? আমি এই অংশ বাস্তবায়ন করতে হবে না, কিন্তু এই লাইন বরাবর নকশা কিনা তা নির্ধারণ করার জন্য কিভাবে এটি করা হবে একটি মোটামুটি ধারণা প্রয়োজন।

সম্পাদনা: এ পর্যন্ত সমস্ত উত্তরগুলির জন্য ধন্যবাদ, তারা বেশ ব্যাপক। আমি আরও একটি জিনিস জানতে চাই: উইন্ডোজ আমার পরিষেবা সম্পর্কে সচেতন কিভাবে? আমি কি নেটিভ উইন্ডোজ ইউটিলিটি দিয়ে এটি পরিচালনা করতে পারি? /Etc/init.d একটি স্টার্ট / স্টপ স্ক্রিপ্ট স্থাপন করার সমতুল্য কি?


হ্যা, তুমি পারো. আমি পাইথনকম লাইব্রেরি ব্যবহার করে এটি অ্যাক্টিভপথন সহ অন্তর্ভুক্ত ActivePython অথবা pywin32 (উইন্ডোজ এক্সটেনশনগুলির জন্য পাইথন) দিয়ে ইনস্টল করা pywin32

এটি একটি সহজ পরিষেবা জন্য একটি মৌলিক কঙ্কাল হয়:

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.main()

    def main(self):
        pass

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

আপনার কোডটি main() পদ্ধতিতে-সাধারণত কোনও অসীম লুপ সহ যা একটি পতাকা পরীক্ষা করে বাধাগ্রস্ত হতে পারে, যা আপনি SvcStop পদ্ধতিতে সেট করেছেন



কোনও উইন্ডোজ এক্সিকিউটেবল একটি পরিষেবা হিসাবে ইনস্টল করার জন্য একটি দম্পতি বিকল্প আছে।

পদ্ধতি 1: rktools.exe থেকে instsrv এবং srvany ব্যবহার করুন

উইন্ডোজ হোম সার্ভার বা উইন্ডোজ সার্ভার 2003 (উইনএক্সপি এর সাথেও কাজ করে), উইন্ডোজ সার্ভার 2003 রিসোর্স কিট সরঞ্জামগুলি ইউটিলিটিগুলির সাথে আসে যা এই জন্য instemrv.exe এবং srvany.exe নামে পরিচিত। এই KB137890 কিভাবে ব্যবহার করবেন তার বিস্তারিত জানার জন্য এই মাইক্রোসফ্ট কেবি নিবন্ধ KB137890 দেখুন।

উইন্ডোজ হোম সার্ভারের জন্য, এই ইউটিলিটিগুলির জন্য যথাযথভাবে " কোনও পরিষেবা ইনস্টলার " নামক একটি দুর্দান্ত ব্যবহারকারী বান্ধব মোড়ক রয়েছে।

পদ্ধতি 2: উইন্ডোজ এনটি জন্য পরিষেবা ইন্সটলার ব্যবহার করুন

উইন্ডোজ এনটি ( এখানে ডাউনলোড করতে সক্ষম ) এর জন্য পরিষেবা ইন্সটলার ব্যবহার করে আরেকটি বিকল্প রয়েছে যা পাইথন নির্দেশাবলী সহ উপলব্ধ । নাম বিপরীত, এটি উইন্ডোজ 2000 এবং উইন্ডোজ এক্সপি উভয় পাশাপাশি কাজ করে। একটি পাইথন স্ক্রিপ্টটি একটি পরিষেবা হিসাবে ইনস্টল করার জন্য এখানে কিছু নির্দেশাবলী দেওয়া হয়েছে।

একটি পাইথন স্ক্রিপ্ট ইনস্টল করা হচ্ছে

একটি নতুন সেবা তৈরি করতে ServiceInstaller চালান। (এই উদাহরণে, এটি ধরা হয় যে পাইথন c: \ Python25 এ ইনস্টল করা আছে)

Service Name  : PythonTest
Display Name : PythonTest 
Startup : Manual (or whatever you like)
Dependencies : (Leave blank or fill to fit your needs)
Executable : c:\python25\python.exe
Arguments : c:\path_to_your_python_script\test.py
Working Directory : c:\path_to_your_python_script

ইনস্টল করার পরে, কন্ট্রোল প্যানেলের পরিষেবাদি অ্যাপলেটটি খুলুন, PythonTest পরিষেবা নির্বাচন করুন এবং শুরু করুন।

আমার প্রাথমিক উত্তর দেওয়ার পরে, আমি লক্ষ্য করেছি যে ইতিমধ্যেই SO এ পোস্ট করা হয়েছে এমন প্রশ্নগুলির সাথে ঘনিষ্ঠভাবে সম্পর্কযুক্ত ছিল। আরো দেখুন:

আমি একটি পাইথন স্ক্রিপ্টটি কোনও পরিষেবা (উইন্ডোজ) হিসাবে চালাতে পারি? কিভাবে?

আমি কিভাবে পাইথনে লিখিত একটি পরিষেবাকে সচেতন করে উইন্ডোজ তৈরি করব?


সবচেয়ে সহজ উপায়টি হল: NSSM - নন-চকিং সার্ভিস ম্যানেজার:

1 - https://nssm.cc/download ডাউনলোড করুন

2 - পাইথন প্রোগ্রামটি একটি পরিষেবা হিসাবে ইনস্টল করুন: অ্যাডমিন হিসাবে Win প্রম্পট

c:> nssm.exe WinService ইনস্টল করুন

3 - এনএসএসএম কনসোলে:

পাথ: সি: \ পাইথন 27 \ Python27.exe

স্টার্টআপ ডিরেক্টরি: সি: \ Python27

আর্গুমেন্ট: c: \ WinService.py

4 - সেবা.এমএসসি তৈরি সেবা পরীক্ষা করুন


আমি pywin32 সঙ্গে একটি সেবা হিসাবে হোস্টিং শুরু।

সবকিছু ভাল ছিল কিন্তু আমি সমস্যাটি পূরণ করেছি যে পরিষেবাটি সিস্টেমের প্রারম্ভে 30 সেকেন্ডের মধ্যে (Windows এর জন্য ডিফল্ট সময়সীমা) শুরু করতে সক্ষম হয়নি। এটি আমার জন্য অত্যন্ত গুরুত্বপূর্ণ কারণ উইন্ডোজ স্টার্টআপটি এক ভৌত মেশিনে হোস্ট করা বেশ কয়েকটি ভার্চুয়াল মেশিনে একযোগে সংঘটিত হয়েছিল এবং আইও লোড বিশাল ছিল। ত্রুটি বার্তা ছিল:

Error 1053: The service did not respond to the start or control request in a timely fashion.

Error 7009: Timeout (30000 milliseconds) waiting for the <ServiceName> service to connect.

আমি পাইউনের সাথে অনেক যুদ্ধ করেছি, কিন্তু এনএসএসএম ব্যবহার করে শেষ পর্যন্ত এই উত্তরটি প্রস্তাব করা হয়েছিল। এটা স্থানান্তরিত করা খুব সহজ ছিল।


পিএসসি: পাইথন এ সার্ভিস কন্ট্রোল ম্যানেজার

উদাহরণ স্ক্রিপ্ট pythonhosted.org থেকে নেওয়া একটি পরিষেবা হিসাবে চালানোর জন্য:

from xmlrpc.server import SimpleXMLRPCServer

from pysc import event_stop


class TestServer:

    def echo(self, msg):
        return msg


if __name__ == '__main__':
    server = SimpleXMLRPCServer(('127.0.0.1', 9001))

    @event_stop
    def stop():
        server.server_close()

    server.register_instance(TestServer())
    server.serve_forever()

তৈরি করুন এবং সেবা শুরু করুন

import os
import sys
from xmlrpc.client import ServerProxy

import pysc


if __name__ == '__main__':
    service_name = 'test_xmlrpc_server'
    script_path = os.path.join(
        os.path.dirname(__file__), 'xmlrpc_server.py'
    )
    pysc.create(
        service_name=service_name,
        cmd=[sys.executable, script_path]
    )
    pysc.start(service_name)

    client = ServerProxy('http://127.0.0.1:9001')
    print(client.echo('test scm'))

বন্ধ করুন এবং সেবা মুছে দিন

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc

ধাপে ব্যাখ্যা করে কিভাবে এটি কাজ করে:

1- উপরে উল্লেখিত মৌলিক কঙ্কাল অনুযায়ী প্রথম একটি পাইথন ফাইল তৈরি করুন। এবং উদাহরণস্বরূপ এটি একটি পাথে সংরক্ষণ করুন: "c: \ PythonFiles \ AppServerSvc.py"

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"


    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                          servicemanager.PYS_SERVICE_STARTED,
                          (self._svc_name_,''))
        self.main()

    def main(self):
        # Your business logic or call to any class should be here
        # this time it creates a text.txt and writes Test Service in a daily manner 
        f = open('C:\\test.txt', 'a')
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            f.write('Test Service  \n')
            f.flush()
            # block for 24*60*60 seconds and wait for a stop event
            # it is used for a one-day loop
            rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
        f.write('shut down \n')
        f.close()

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

2 - এই পদক্ষেপে আমরা আমাদের সেবা নিবন্ধন করা উচিত।

প্রশাসক হিসাবে কমান্ড প্রম্পট চালান এবং টাইপ করুন:

Sc TestService binpath = "C: \ Python36 \ Python.exe c: \ PythonFiles \ AppServerSvc.py" DisplayName = "TestService" start = auto

binpath প্রথম যুক্তি python.exe পথ

binpath এর দ্বিতীয় যুক্তিটি আপনার পাইথন ফাইলের পথ যা আমরা ইতিমধ্যে তৈরি করেছি

প্রতিটি " = " চিহ্নের পরে আপনাকে একটি স্থান রাখতে হবে তা মিস করবেন না।

তারপর সবকিছু ঠিক আছে, আপনি দেখতে হবে

[এসসি] CreateService সফলতা

এখন আপনার পাইথন পরিষেবা এখন উইন্ডোজ সেবা হিসাবে ইনস্টল করা হয়। আপনি পরিষেবা পরিচালক এবং রেজিস্ট্রি এ এটি দেখতে পারেন:

HKEY_LOCAL_MACHINE \ সিস্টেম \ CurrentControlSet \ সার্ভিস \ TestService

3 - এখন ঠিক আছে। আপনি পরিষেবা ব্যবস্থাপক আপনার সেবা শুরু করতে পারেন।

আপনি প্রতিটি পাইথন ফাইলটি চালাতে পারেন যা এই পরিষেবা কঙ্কাল সরবরাহ করে।


যদিও আমি কয়েক সপ্তাহ আগে নির্বাচিত উত্তরটি আপত্তিকর করেছি, তবুও আমি এই বিষয়ে অনেক বেশি সংগ্রাম করেছি। এটি একটি বিশেষ পাইথন ইনস্টলেশন এবং একটি পরিষেবা হিসাবে একটি স্ক্রিপ্ট চালানোর জন্য বিশেষ মডিউল ব্যবহার করে মনে হয় কেবল ভুল উপায়। পোর্টেবিলিটি এবং যেমন কি?

আমি বিস্ময়কর নন-চিংকিং সার্ভিস ম্যানেজার জুড়ে হিংস্র হয়ে পড়েছিলাম, এটি উইন্ডোজ পরিষেবাদির সাথে মোকাবিলা করার জন্য এটি সত্যিই সহজ এবং সরল ছিল। আমি যেহেতু একটি ইনস্টল করা পরিষেবায় বিকল্পগুলি পাস করতে পারছি, তাই আমি আমার পাইথন এক্সিকিউটেবল নির্বাচন করতে এবং বিকল্প হিসাবে আমার স্ক্রিপ্টটি পাস করতে পারি।

আমি এখনো এই সমাধানটি চেষ্টা করিনি, তবে আমি এখনই এটিকে করব এবং প্রক্রিয়া সহ এই পোস্টটি আপডেট করব। আমি উইন্ডোজ ভার্চুয়ালেনভ ব্যবহার করতে আগ্রহী, তাই আমি শীঘ্রই বা পরে একটি টিউটোরিয়াল নিয়ে আসতে পারি এবং এখানে লিঙ্ক।







cross-platform