Gitlab Webhooks, External Services, and API(二)
一. 使用webhooks
webhook 是一个API的概念,并且变得越来越流行。我们能用事件描述的事物越多,webhook的作用范围也就越大。webhook作为 个轻量的事件处理应用,正变得越来越有用。
准确的说webhook是一种web回调或者http的push API, 是向APP或者其它应用提供实时信息的一种方式。webhook在数据产生时立即发送数据,也就是我能实时收到数据。这一种不同于典型的API,需要用了实时性需要足够快的轮询。这无论是对生产还是对消费者都是高效的,唯一的缺点是初始建立困难。
webhook有时也被称为反加API, 因为他提供了API规则,你需要设计要使用的API。WEBHOOK将向你的应用发起http请求,典型的是post请求,应用程序由请求驱动。
1. 搭建要使用的到的服务器RequestBin.(此处我把服务器部署到docker上面的)
(1)刻隆代码
[root@c720120 ~]# git clone git://github.com/Runscope/requestbin.git
Cloning into 'requestbin'...
remote: Counting objects: 636, done.
remote: Total 636 (delta 0), reused 0 (delta 0), pack-reused 636
Receiving objects: 100% (636/636), 652.55 KiB | 397.00 KiB/s, done.
Resolving deltas: 100% (304/304), done.
(2)进入到项目的目录,进行构建和启动容器。
[root@c720120 ~]# cd requestbin/
[root@c720120 requestbin]# docker-compose build
redis uses an image, skipping
Building app
Step 1/8 : FROM python:2.7-alpine
2.7-alpine: Pulling from library/python
ff3a5c916c92: Already exists
5556c6f99b85: Pull complete
93fbc81365bc: Pull complete
8780cd897032: Pull complete
Digest: sha256:cbc1c1c227012034793083306f6f6322e0276ca134c218cc49b131ca59df7699
Status: Downloaded newer image for python:2.7-alpine
---> a448d7554c75
Step 2/8 : RUN apk update && apk upgrade && apk add gcc python python-dev py-pip musl-dev bsd-compat-headers libevent-dev && rm -rf /var/cache/apk/*
---> Running in e57172cecb26
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
v3.7.0-214-g519be0a2d1 [http://dl-cdn.alpinelinux.org/alpine/v3.7/main]
v3.7.0-207-gac61833f9b [http://dl-cdn.alpinelinux.org/alpine/v3.7/community]
OK: 9054 distinct packages available
Upgrading critical system libraries and apk-tools:
(1/1) Upgrading apk-tools (2.8.2-r0 -> 2.9.1-r2)
Executing busybox-1.27.2-r7.trigger
Continuing the upgrade transaction with new apk-tools:
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/6) Upgrading libressl2.6-libcrypto (2.6.4-r2 -> 2.6.5-r0)
(2/6) Upgrading libressl2.6-libssl (2.6.4-r2 -> 2.6.5-r0)
(3/6) Upgrading busybox (1.27.2-r7 -> 1.27.2-r11)
Executing busybox-1.27.2-r11.post-upgrade
(4/6) Installing libressl2.6-libtls (2.6.5-r0)
(5/6) Installing ssl_client (1.27.2-r11)
(6/6) Upgrading freetype (2.8.1-r2 -> 2.8.1-r3)
Executing busybox-1.27.2-r11.trigger
Executing ca-certificates-20171114-r0.trigger
OK: 32 MiB in 43 packages
(1/21) Installing bsd-compat-headers (0.7.1-r0)
(2/21) Installing binutils-libs (2.30-r1)
(3/21) Installing binutils (2.30-r1)
(4/21) Installing gmp (6.1.2-r1)
(5/21) Installing isl (0.18-r0)
(6/21) Installing libgomp (6.4.0-r5)
(7/21) Installing libatomic (6.4.0-r5)
(8/21) Installing pkgconf (1.3.10-r0)
(9/21) Installing libgcc (6.4.0-r5)
(10/21) Installing mpfr3 (3.1.5-r1)
(11/21) Installing mpc1 (1.0.3-r1)
(12/21) Installing libstdc++ (6.4.0-r5)
(13/21) Installing gcc (6.4.0-r5)
(14/21) Installing libffi (3.2.1-r4)
(15/21) Installing python2 (2.7.14-r2)
(16/21) Installing libevent (2.1.8-r2)
(17/21) Installing libevent-dev (2.1.8-r2)
(18/21) Installing musl-dev (1.1.18-r3)
(19/21) Installing py-setuptools (33.1.1-r1)
(20/21) Installing py2-pip (9.0.1-r1)
(21/21) Installing python2-dev (2.7.14-r2)
Executing busybox-1.27.2-r11.trigger
OK: 185 MiB in 64 packages
Removing intermediate container e57172cecb26
---> bff0b149a3c4
Step 3/8 : ADD requirements.txt /opt/requestbin/
---> 40174275a7cb
Step 4/8 : RUN pip install -r /opt/requestbin/requirements.txt && rm -rf ~/.pip/cache
---> Running in 1ecc38d40702
Collecting gevent==1.0.2 (from -r /opt/requestbin/requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/8a/71/9bb13513d39c513fa71344d57a11affd6ccad775575458f435ff9142daf5/gevent-1.0.2.tar.gz (1.7MB)
Collecting greenlet==0.4.1 (from -r /opt/requestbin/requirements.txt (line 2))
Downloading https://files.pythonhosted.org/packages/c6/9a/dbb2c9acbde5f2f48e94b9eeacfda511373dfb5534aae8679c06d485419f/greenlet-0.4.1.zip (75kB)
Collecting ProxyTypes==0.9 (from -r /opt/requestbin/requirements.txt (line 3))
Downloading https://files.pythonhosted.org/packages/72/bd/24f45710e7e6909b2129332363be2c981179ed2eda1166f18bc2baef98a1/ProxyTypes-0.9.zip
Collecting nose==1.3.0 (from -r /opt/requestbin/requirements.txt (line 4))
Downloading https://files.pythonhosted.org/packages/de/f4/b205776cf5cbddbc1e2c3223fa29c0d05f18a9b8afad8cfa23438c217434/nose-1.3.0.tar.gz (404kB)
Requirement already satisfied: wsgiref==0.1.2 in /usr/local/lib/python2.7 (from -r /opt/requestbin/requirements.txt (line 5)) (0.1.2)
Collecting feedparser==5.1.3 (from -r /opt/requestbin/requirements.txt (line 6))
Downloading https://files.pythonhosted.org/packages/eb/d7/143dc058551243c11f76e18117d3818135377049eaadc4edc30a3f34b1d3/feedparser-5.1.3.tar.bz2 (202kB)
Collecting Jinja2==2.7 (from -r /opt/requestbin/requirements.txt (line 7))
Downloading https://files.pythonhosted.org/packages/33/db/9931c645626f9bf7867cc3c4225e7a8abf7aff37ecddb7e7d5df90a3b6c4/Jinja2-2.7.tar.gz (377kB)
Collecting Werkzeug==0.9.3 (from -r /opt/requestbin/requirements.txt (line 8))
Downloading https://files.pythonhosted.org/packages/8d/3b/79b28e9436f321763bfa47d7784bedb8f0b6b7da92b2979ee5a2a60f3bc6/Werkzeug-0.9.3.tar.gz (1.1MB)
Collecting Flask==0.10.1 (from -r /opt/requestbin/requirements.txt (line 9))
Downloading https://files.pythonhosted.org/packages/db/9c/149ba60c47d107f85fe52564133348458f093dd5e6b57a5b60ab9ac517bb/Flask-0.10.1.tar.gz (544kB)
Collecting Flask-Cors==3.0.2 (from -r /opt/requestbin/requirements.txt (line 10))
Downloading https://files.pythonhosted.org/packages/4f/4f/ea10ca247c21b6512766cf730621697ec2766fb2f712245b2c00983a57b1/Flask_Cors-3.0.2-py2.py3-none-any.whl
Collecting redis==2.7.6 (from -r /opt/requestbin/requirements.txt (line 11))
Downloading https://files.pythonhosted.org/packages/e7/6f/446e6d3cbb6f43d5f73de1be12cd8d033a6f4456ddd8a9dc4cdbd53b389f/redis-2.7.6.tar.gz (76kB)
Collecting msgpack-python==0.1.12 (from -r /opt/requestbin/requirements.txt (line 12))
Downloading https://files.pythonhosted.org/packages/c0/0c/cc5e51b2f82ddee4ceb35e8bceed0545d0c5d2ee632a48a403e46a3495ec/msgpack-python-0.1.12.tar.gz (49kB)
Collecting python-dateutil==2.1 (from -r /opt/requestbin/requirements.txt (line 13))
Downloading https://files.pythonhosted.org/packages/65/52/9c18dac21f174ad31b65e22d24297864a954e6fe65876eba3f5773d2da43/python-dateutil-2.1.tar.gz (152kB)
Collecting gunicorn (from -r /opt/requestbin/requirements.txt (line 14))
Downloading https://files.pythonhosted.org/packages/55/cb/09fe80bddf30be86abfc06ccb1154f97d6c64bb87111de066a5fc9ccb937/gunicorn-19.8.1-py2.py3-none-any.whl (112kB)
Collecting bugsnag (from -r /opt/requestbin/requirements.txt (line 15))
Downloading https://files.pythonhosted.org/packages/64/c5/141fb591b4a460dc169f6ab4a31bd8532bf72c2becf791beb7aa1669676e/bugsnag-3.4.2-py2-none-any.whl (41kB)
Collecting blinker (from -r /opt/requestbin/requirements.txt (line 16))
Downloading https://files.pythonhosted.org/packages/1b/51/e2a9f3b757eb802f61dc1f2b09c8c99f6eb01cf06416c0671253536517b6/blinker-1.4.tar.gz (111kB)
Collecting markupsafe (from Jinja2==2.7->-r /opt/requestbin/requirements.txt (line 7))
Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Collecting itsdangerous>=0.21 (from Flask==0.10.1->-r /opt/requestbin/requirements.txt (line 9))
Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
Collecting Six (from Flask-Cors==3.0.2->-r /opt/requestbin/requirements.txt (line 10))
Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Collecting webob (from bugsnag->-r /opt/requestbin/requirements.txt (line 15))
Downloading https://files.pythonhosted.org/packages/d2/df/9b3b374ea2a82b875a90d1fdcf2c4a652d48f0d1e7c2d1034d636551d4d2/WebOb-1.8.2-py2.py3-none-any.whl (115kB)
Building wheels for collected packages: gevent, greenlet, ProxyTypes, nose, feedparser, Jinja2, Werkzeug, Flask, redis, msgpack-python, python-dateutil, blinker, markupsafe, itsdangerous
Running setup.py bdist_wheel for gevent: started
Running setup.py bdist_wheel for gevent: still running...
Running setup.py bdist_wheel for gevent: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/bf/65/92/5950be5cabfc31ddba3d510e8ebbed6112aba18016472c4aec
Running setup.py bdist_wheel for greenlet: started
Running setup.py bdist_wheel for greenlet: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/9b/00/8b/8064203a9e62f04e7ed1cf5cac6f3ddd695ab74353fd68f8b4
Running setup.py bdist_wheel for ProxyTypes: started
Running setup.py bdist_wheel for ProxyTypes: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/c8/24/65/9797c6999f4d45b25de4d0f280d7ff0b12061eddd750fcc23c
Running setup.py bdist_wheel for nose: started
Running setup.py bdist_wheel for nose: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/9e/23/4a/6d694db85896e8a420efb47a353b7001b2972768f07458f9ea
Running setup.py bdist_wheel for feedparser: started
Running setup.py bdist_wheel for feedparser: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/7b/49/19/8199a0729fd8d58e4f3616d96a7a0e69581b2c046560b52608
Running setup.py bdist_wheel for Jinja2: started
Running setup.py bdist_wheel for Jinja2: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/4d/66/ac/118b76f63c3443b318dc5ee1ba1e39335032305e96cd4dafa0
Running setup.py bdist_wheel for Werkzeug: started
Running setup.py bdist_wheel for Werkzeug: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/e6/fb/6e/4b753478730a5478125485dc99821ff7f4a818ce3cf48abebf
Running setup.py bdist_wheel for Flask: started
Running setup.py bdist_wheel for Flask: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/e1/f2/be/1c4f307a41aad7e632f79c0242a2714ecde24b663da3519665
Running setup.py bdist_wheel for redis: started
Running setup.py bdist_wheel for redis: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/5b/67/92/70dbc6b8e4f01984adde8953dd6319542a7bfee09949d15be9
Running setup.py bdist_wheel for msgpack-python: started
Running setup.py bdist_wheel for msgpack-python: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/94/52/11/ff262175c66991cdec599d3c90bba11ce5a0eab1aac008aa97
Running setup.py bdist_wheel for python-dateutil: started
Running setup.py bdist_wheel for python-dateutil: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/a3/b4/9e/be446328c3728631f286e9cc832b8b00ca99480eefa1a6db4e
Running setup.py bdist_wheel for blinker: started
Running setup.py bdist_wheel for blinker: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/92/a0/00/8690a57883956a301d91cf4ec999cc0b258b01e3f548f86e89
Running setup.py bdist_wheel for markupsafe: started
Running setup.py bdist_wheel for markupsafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5
Successfully built gevent greenlet ProxyTypes nose feedparser Jinja2 Werkzeug Flask redis msgpack-python python-dateutil blinker markupsafe itsdangerous
gevent 1.0.2 has requirement greenlet>=0.4.7, but you'll have greenlet 0.4.1 which is incompatible.
Installing collected packages: greenlet, gevent, ProxyTypes, nose, feedparser, markupsafe, Jinja2, Werkzeug, itsdangerous, Flask, Six, Flask-Cors, redis, msgpack-python, python-dateutil, gunicorn, webob, bugsnag, blinker
Successfully installed Flask-0.10.1 Flask-Cors-3.0.2 Jinja2-2.7 ProxyTypes-0.9 Six-1.11.0 Werkzeug-0.9.3 blinker-1.4 bugsnag-3.4.2 feedparser-5.1.3 gevent-1.0.2 greenlet-0.4.1 gunicorn-19.8.1 itsdangerous-0.24 markupsafe-1.0 msgpack-python-0.1.12 nose-1.3.0 python-dateutil-2.1 redis-2.7.6 webob-1.8.2
Removing intermediate container 1ecc38d40702
---> 0288f2dee287
Step 5/8 : ADD requestbin /opt/requestbin/requestbin/
---> d1996b2ee224
Step 6/8 : EXPOSE 8000
---> Running in b360b0050182
Removing intermediate container b360b0050182
---> 4a550b4ecbdc
Step 7/8 : WORKDIR /opt/requestbin
Removing intermediate container 416d34676426
---> 3d6af8d85ffa
Step 8/8 : CMD gunicorn -b 0.0.0.0:8000 --worker-class gevent --workers 2 --max-requests 1000 requestbin:app
---> Running in da2a42b95fca
Removing intermediate container da2a42b95fca
---> 8840f59e26d9
Successfully built 8840f59e26d9
Successfully tagged requestbin_app:latest
[root@c720120 requestbin]# docker-compose up -d
Creating requestbin_redis_1 ... done
Creating requestbin_app_1 ... done