Triển khai hệ thống Mongo-Shake

Posted: Tháng Tư 19, 2019 in MongoDB
Thẻ:, ,

1. Giới thiệu

Cho mục đích dự phòng hệ thống khi có thảm họa, như trường hợp đơn giản là mất điện ở ISP, trường hợp điển hình có thể thấy gần đây là vụ sập data center VNG tháng 9/2018, khi đó chúng ta cần dựng hệ thống tại nhiều data center khác nhau.

Trong trường hợp dự phòng hệ thống MongoDB, chúng ta cũng dựng hệ thống ở nhiều data center khác nhau. MongoDB có hỗ trợ kỹ thuật replica set để cho phép replication dữ liệu qua nhiều node với mô hình master/slave. Với replica set, hệ thống chỉ có một master, vì vậy mà mô hình cũng chỉ có một active. Để cho phép hệ thống MongoDB có nhiều master, active ở nhiều data center và có thể dự phòng được dữ liệu, chúng ta cần sử dụng một công cụ mở rộng. Trong phần này tôi sẽ giới thiệu về Mongo-Shake.

1.1 Về Mongo-Shake

Mongo-Shake là nền tảng cho phép replication dữ liệu dựa trên oplog của MongoDB. Nó đọc logs hoạt động oplog của cụm MongoDB và thực hiện nhân bản dữ liệu MongoDB và thực hiện các yêu cầu cụ thể tiếp theo dựa trên log hoạt động. Ngoài tính năng chính là đồng bộ dữ liệu cluster MongoDB, Mongo-Shake còn hỗ trợ một số tình huống khác như: nhân bản bất đồng bộ, đồng bộ cache, giám sát dựa vào log

1.2 Tính năng và mô hình hoạt động

Mongo-Shake tìm nạp oplog từ mongodb nguồn và thực hiện phát lại (replay) vào mongodb đích hoặc gửi đến các điểm khác trong các tunnel khác nhau. Mongo-Shake hỗ trợ một số tunnel sau:

  • Direct: Thực hiện ghi trực tiếp MongoDB đích

  • RPC: Kết nối qua net/rpc vào go

  • TCP: Kết nối qua TCP socket

  • File: Kết nối qua một tệp tin

  • Kafka: Kết nối qua một kênh kafka

Một số tính năng của Mongo-Shake:

  • Parallel Replication
  • High Availability

  • Filter

  • Compress

  • Gid

  • Checkpoint

  • Troubleshouting và Speed Limit

  • Conflict Detection

Ảnh dưới mô tả tổng quan luồng dữ liệu của Mongo-Shake

dataflow mongo-shake

 

dataflow_2

Source MongoDB ở đây có thể là mongod đơn, replica set hoặc sharding. Destination MongoDB có thể là mongod hoặc mongos. Nếu source là replica set, khi đó chúng ta sẽ tìm nạp dữ liệu từ secondary/hidden để giảm áp lực lên primary.

2. Triển khai Replica set MongoDB và Mongo-Shake

2.1 Mô hình thực hiện

Chúng ta thực hiện thiết lập mô hình đơn giản như sau:

sync-mongodb-in-2-datacenters

Requirement

05+ server centos 7

  • 01 server (192.168.10.110) cài go-1.9+, govendor, git và Mongo-Shake
  • 02+ server (192.168.10.111-112) thiết lập replica set mongodb (replicate set id: mongoshake1)

  • 02+ server (192.168.10.113-114) thiết lập replica set mongodb (replicate set id: mongoshake2)

2.2 Thiết lập replica set MongoDB

a. Cài đặt MongoDB 3

Chúng ta thực hiện cài đặt MongoDB 3x trên các server mà sẽ thực hiện nhiệm vụ MongoDB server.

Step1: Thực hiện tạo repo mongodb

cat >/etc/yum.repos.d/mongo.repo<<EOF
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
EOF

Step2: Cài đặt MongoDB

Cài đặt

yum install mongodb-org -y

Cho phép truy cập mongodb server từ một số IP

sed -i 's/127.0.0.1/0.0.0.0/' /etc/mongod.conf

Step3: Thiết lập firewall

Chỉ cho phép vùng mạng hoặc những IP cần thiết được phép truy cập MongoDB

firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" port port="27017" protocol="tcp" accept'
firewall-cmd --reload

Step4: Start mongod

systemctl start mongod.service
systemctl enable mongod.service

b. Replica set MongoDB tại cụm cluster01

Thiết lập replica set mongodb với id là mongoshake1

Step1: Enable replication trên các MongoDB

Chỉnh tệp tin mongod.conf và thêm tùy chọn sau

cat >>/etc/mongod.conf <<EOF
replication:
    #replica set id
    replSetName: mongoshake1
EOF
  • Restart mongod
systemctl restart mongod

Step2: Thiết lập hostname

cat >>/etc/hosts <<EOF
192.168.10.111    mongo01
192.168.10.112    mongo02
EOF

Step3: Khởi tạo replica set

Thực hiện khởi tạo replica set mongodb trên server mongo01

mongo
>rs.initiate( { _id: "mongoshake1", members: [ { _id: 0, host: "mongo01:27017", priority: 2 } ] } )
>rs.add({ _id:2,host:"mongo02:27017",priority:1 })

c. Replica set MongoDB tại cụm cluster02

Thiết lập replica set mongodb với id là mongoshake2

Step1: Enable replication trên các MongoDB

Chỉnh tệp tin mongod.conf và thêm tùy chọn sau

cat >>/etc/mongod.conf <<EOF
replication:
    #replica set id
    replSetName: mongoshake2
EOF
  • Restart mongod
systemctl restart mongod

Step2: Thiết lập hostname

cat >>/etc/hosts <<EOF
192.168.10.113    mongo03
192.168.10.114    mongo04
EOF

Step3: Khởi tạo replica set

Thực hiện khởi tạo replica set mongodb trên server mongo01

mongo
>rs.initiate( { _id: "mongoshake2", members: [ { _id: 0, host: "mongo03:27017", priority: 2 } ] } )
>rs.add({ _id:2,host:"mongo04:27017",priority:1 })

2.3 Thiết lập Mongo-Shake

a. Cài đặt Go language

  • Download go language

Download go at https://golang.org/dl/

curl -O https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz
tar -C /usr/local -xzvf go1.12.4.linux-amd64.tar.gz
  • Thiết lập environments
cat >>~/.bashrc<<EOF
export GOPATH=/root/mongo-shake
export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin
EOF
  • Logout and login

b. Cài đặt govendor

yum install git gcc -y
go get -u github.com/kardianos/govendor
cp  mongo-shake/bin/govendor /usr/local/go/bin/
rm -rf /root/mongo-shake

c. Thiết lập Mongo-Shake

  • Download mongo-shake
cd /root
git clone https://github.com/aliyun/mongo-shake.git
  • pull all dependencies & build collector
cd /root/mongo-shake/src
govendor sync
cd /root/mongo-shake
./build.sh
  • Sửa nội dung source và destination mongodb trong tệp conf/collector.conf như sau
mongo_urls = mongodb://192.168.10.111:27017,192.168.10.112:27017
tunnel.address = mongodb://192.168.10.113:27017,192.168.10.114:27017
  • Chạy Mongo-Shake
./bin/collector -conf=conf/collector.conf

Tham khảo thêm tại:

https://github.com/alibaba/MongoShake

Advertisements

1. Kết nối GSM gateway Yearstar TG200 và FreePBX

Hướng dẫn step-by-step cách cấu hình kết nối GSM Gateway và FreePBX (GSM Gateway trong trường hợp này tôi sẽ sử dụng Yeastar TG200 cho test). Khi đó GSM trunk trên Yearstar TG200 sẽ mở rộng trên hệ thống FreePBX. Mục đích đạt được:

  • Thực hiện cuộc gọi ra từ hệ thống FreePBX qua GSM trunks của Yearstar gateway.

  • Thực hiện nhận cuộc gọi từ bên ngoài vào thông qua hệ thống GSM trunks of Yearstar gateway đến hệ thống FreePBX

Mô hình hệ thống như sau:

gsm-gateway-freepbx

Thông số sẽ thực hiện:

  • GSM Gateway Yearstar TG200 và FreePBX sử dụng chế độ Service provider để thực hiện kết nối với nhau.
  • Yearstar TG200: 192.168.10.117/24

  • FreePBX: 192.168.10.118/24

  • GSM2: +84906226654

1.1 Tạo VoIP Trunk trên TG200

Path: Gateway> VoIP Settings> VoIP trunk> Add VoIP Trunk.
Khi đó thực hiện chọn mode là “Service Provider”, và điền địa chỉ IP của FreePBX (192.168.10.118)

add-extensions

Trong đó:

  • Trunk Type: Service Provider
  • Type: SIP

  • Provider Name: FreePBX

  • Hostname/IP: địa chỉ IP của FreePBX server (192.168.10.118)

Sau đó thực hiện Save → Apply

Kiểm tra trạng thái trunk

trunk-status

1.2 Tạo VoIP Trunk trên FreePBX

Path: Connectivity> Trunks> Add Trunks> Add SIP (chan_pjsip) Trunk

voip-trunk-freepbx

Vào thông tin trong tab General, với Trunk Name là “TG200”

add-trunk-name

Tiếp đến, chuyển qua tab pjsip Settings để thiết lập PJSIP

Ở tab General:

add-trunk-general

  • Chọn chế độ “Authentication” là None, để tắt chứng thực
  • Vào thông tin SIP server là địa chỉ IP của GSM TG200 gateway (192.168.10.117)

  • SIP Server Port là 5060 (default)

Tiếp tục qua tab Advanced:

add-trunk-advanced

  • Chọn giá trị No cho “Permanent Auth Rejection” để không bắt lỗi chứng thực khi gateway kết nối.
  • Vào thông tin From Domain là địa chỉ IP của gateway, mục đích là khi gateway request đến trunk trên FreePBX nó sẽ hiện thông tin header request của gateway TG200.

Sau đó thực hiện Submit → Apply Config

1.3 Tạo một extension trên FreePBX

Mở Applications> Extensions> Add Extension> Add New Chan_SIP Extension

Add-SIP-Extension

Thực hiện tạo một extension Chan_SIP với thông tin:

  • User Extension: Vào thông tin số mở rộng dùng khi dial
  • Display Name: Thiết lập tên hiển cho số này khi gọi

  • Secret: Vào thông tin mật khẩu cho tài khoản này

Note: Cả Chan_SIP và PJSIP đều có thể cho phép tạo extension number nhưng Chan_SIP cho phép hỗ trợ NAT. Hiện tại thì PJSIP được sử dụng cho default SIP (với port 5060), Chan_SIP sử dụng port 5160.

Để tạo các tài khoản khoản cho SIP extension gồm cả Chan_SIP và PJSIP, chúng ta thực hiện như các bước ở trên.

2. Cấu hình Incoming call vào FreePBX

Phần này, chúng ta sẽ cấu hình để cho phép thực hiện cuộc vào từ bên ngoài vào hệ thống FreePBX. Cuộc gọi đầu tiên sẽ đi qua GSM gateway TG200. TG200 sẽ chuyển tiếp cuộc gọi vào hệ thống FreePBX. FreePBX thực hiện phân phối cuộc gọi đến số extension phù hợp.

2.1 Tạo route Mobile to IP trên TG200

Trên TG200, Mở Gateway> Route Settings > Mobile to IP

route-to-freepbx

Vào các thông tin sau:

  • Simple Mode: No (để show thêm một số thông tin tùy chọn, nếu chọn Yes thì cấu hình ở chế độ rút gọn)
  • Route Name: đặt tên để route từ gateway TG200 đến FreePBX, ở đây đặt tên To_FreePBX

  • Call Source: Hiện tại tôi đang cắm SIM ở khe số 02, vì vậy chọn Mobile-GSM2. Ở đây, chúng ta gắn sim ở khe nào thì chọn Call Source phù hợp.

  • Call Destination: Lựa chọn SPS-FreePBX. Khi đó tất cả cuộc gọi đến GSM2 sẽ được chuyển đến FreePBX qua trunk này.

  • Hotline: 999, đặt một số bất kỳ mà cùng với số DID trên FreePBX trong cấu hình inbound và outbound. Thường ta đặt là số Sim card hoặc số serial Sim.

2.2 Cấu hình Inbound Route trên FreePBX

Thực hiện cấu hình “Inbound Routes” để cho phép nhận chuyển tiếp từ gateway TG200 vào FreePBX

Mở Connectivity> Inbound Routes> Add Inbound Route

inbound-route

  • Description: Vào thông tin mô tả cho Inbound Routes
  • DID Number: 999 (cùng thông tin số hotline trên TG200)

  • Set Destination: Chọn Extension và chọn số extension đã tạo, ở đây là 100. Khi đó từ bên ngoài gọi vào số mobile gắn trên sim, sẽ chuyển tiếp cuộc gọi đến thiết bị cài đặt SIP có extension 100.

3. Cấu hình Outgoing call từ FreePBx qua TG200

Phần này, chúng ta sẽ cấu hình để cho phép thực hiện cuộc vào từ một số extension ra ngoài qua TG200. Đầu tiên cuộc gọi từ FreePBX sẽ kết nối GSM gateway TG200. TG200 chọn một giá trị định tuyến phù hợp, mà sẽ qua GSM nào (có thể qua một GSM hoặc một nhóm GSM) và thực hiện kết nối ra bên ngoài.

Thực hiện cấu hình như sau:

3.1 Cấu hình Outbound Route trên FreePBX

Mở FreePBX > Connectivity> Outbound routes> Add Outbound Route

outbound-route-settings

Tab “Route Settings”, vào các thông tin như sau:

  • Route Name: Vào tên cho route, ở đây là To_TG200
  • Trunk Sequence for Matched Routes: Chọn tên Trunk đã tạo ở 2.2 cho kết nối Trunk đến gateway TG200. Ở đây tên Trunk đã tạo trước đó là “TG200”

Tiếp đó chuyển qua tab Dial Parterns

outbound-route-dial

  • prefix: 9. Là số đứng trước số cần gọi ra (Ví dụ gọi 0988888888, thì từ thiết bị cài đặt số extension sẽ ấn các phím 90988888888 để thực hiện cuộc gọi ra)
  • match parttern: chúng ta vào giá trị “X.” (X đúng với giá trị các số 0-9)

3.2 Tạo route IP to Mobile trên TG200

Mở TG200 → Gateway → Route Settings → IP to Mobile → Add IP to Mobile Route

route-from-freepbx

Với các thông tin sau:

  • Route Name: Đặt tên route, From_FreePBX
  • Call Source: Lựa chọn SPS-FreePBX

  • Call Destination: Chọn khe sim 2 (GSM2) đang kết nối.

4. Kiểm tra cuộc gọi

Step1: Cài đặt phần mềm VoIP

Tìm phần mềm nào hỗ trợ VoIP thì thực hiện cài đặt. Ở đây tôi dùng Zoiper thấy khá ổn, có cả bản trên mobile và computer.

Thực hiện thiết lập SIP account trên Zoiper với thông tin extension đã tạo trên FreePBX

register-sip-account

Step2: Kiểm tra cuộc gọi vào

Sử dụng mobile gắn sim và thực hiện cuộc gọi vào số gắn trên GSM2. Khi đó kiểm tra trên thiết bị cài đặt extension 100

test-incoming-call

Khi đó nhận được cuộc gọi từ số mobile hiện

Step3: Kiểm tra cuộc gọi ra

Từ thiết bị mà cài đặt extension, thực hiện gọi ra một số mobile

test-outgoing-call

1. Cài đặt FreePBX

Download Freepbxdistro at http://downloads.freepbxdistro.org/ISO/

FreePBX distro các bản mới có tên gọi là SNG7-FPBX, nó dựa trên bản phân phối RHEL7.

Bản mới nhất hiện đang là SNG7-FPBX-1805, gồm các thành phần chính sau:

  • FreePBX 14
  • CentOS 7
  • Asterisk 13 or 15

Download tại: SNG7-FPBX-64bit-1805-2.iso

Sau khi cài đặt xong, truy cập FreePBX server và cấu hình network. Cách cấu hình network tương tự với CentOS/RHEL.

DEVICE="eth0"
ONBOOT="yes"
IPADDR=192.168.10.118
NETMASK=255.255.255.0
GATEWAY=192.168.10.1
DNS1=8.8.8.8
DNS2=1.1.1.1

Sau đó thực hiện restart network
systemctl restart network

Tiếp theo mở web browser và truy cập FreePBX theo địa chỉ http://192.168.10.118

Màn hình khởi tạo đầu tiên yêu cầu tạo tài khoản cho quản trị hệ thống FreePBX.

Initial-FreePBX-Administration

Sau khi vào thông tin tài khoản, nhấn Create Account để tạo tài khoản quản trị.

Màn hình chính FreePBX, xuất hiện gồm 04 options:

home-login

  • FreePBX Administration: cho phép chúng ta cấu hình FreePBX, với thông tin tài khoản quản trị vừa tạo ở trên.
  • User Control Panel: Là nơi người dùng có thể login và thực hiện gọi qua giao diện web, thiết lập nút phone, xem voicemail, gửi tin nhắn SMS & XMPP, … (Thông tin tài khoản login cho option này nằm ở module User Management
  • Operator Panel: Là màn hình mà cho phép operator để kiểm soát cuộc gọi
  • Get Support: Chuyển hướng support sang trang chủ FreePBX

Chúng ta chọn “FreePBX Administration” để login vào trang quản trị FreePBX

Tại màn hình chính là Dashboard của FreePBX với các thông tin tổng quan, thống kê số liệu hệ thống, network, trạng thái dịch vụ, …

dashboard-freepbx

2. Tạo extension – máy nhánh

Chúng ta thực hiện tạo số máy nhánh (hay SIP Account hoặc Extension)

Trong giao diện chính mở: Applications> Extensions> Add Extension> Add New Chan_SIP Extension

add-extensions

Thực hiện tạo một extension Chan_SIP với thông tin:

  • User Extension: Vào thông tin số máy nhánh dùng khi dial, ở đây là 100
  • Display Name: Thiết lập tên hiển thị KeepWalking cho số nhánh này
  • Secret: Vào thông tin mật khẩu cho tài khoản này (Ở đây tôi đặt P@ssw0rd)

Note: Cả Chan_SIP và PJSIP đều cho phép tạo extension number nhưng Chan_SIP cho phép hỗ trợ NAT. Hiện tại thì PJSIP được sử dụng cho default SIP (với port 5060), Chan_SIP sử dụng port 5160.

Để tạo các tài khoản khoản cho SIP extension gồm cả Chan_SIP và PJSIP, chúng ta thực hiện như các bước ở trên.

show-extensions

3. Thiết lập chuyển hướng cuộc gọi

Trên giao diện web của FreePBX, chúng ta có thể cấu hình để cho phép chuyển hướng cuộc gọi (với tùy chọn Follow Me) từ một số khi số đó không answer hoặc busy.

Chúng ta cấu hình chuyển hướng cuộc gọi từ số 100 đến 101 khi số máy 100 không answer hoặc busy.

Step1: Enable Follow Me

Mở Applications → Follow Me

enable-follow-me

Khi đó chọn Yes cho số extension cần enabled tính năng Follow Me

Step2: Edit extensions

Mở Applications → Extensions (Hoặc mở Application → Follow Me)

Khi đó chọn số extension cần edit, ví dụ ở đây là 100

edit-follow-me

Khi đó vào các thông số sau:

  • Ring Time (max 60 sec): thiết lập khoảng thời gian tối đa rung chuông, nếu sau khoảng thời gian này extension 100 không trả lời thì sẽ forward sang Extensions 101. Ta thiết lập khoảng time là 20sec.
  • Destination if no answer: chọn Extension và chọn số nhánh sẽ forward. Ở đây, chúng ta thiết lập khi số 100 không answer hoặc busy thì sẽ forward cuộc gọi đến số 101.
    Cuối cùng nhấn Submit → Apply Config

4. Hệ thống trả lời tự động – IVR

Mục đích phát thông điệp từ tệp audio đến người gọi (caller) từ bên ngoài gọi vào hệ thống tổng đài. Các bước thực hiện như sau:

Step1: Tạo System Recordings

Chúng ta sẽ cấu hình module System Recordings để ghi âm hoặc upload các tệp tin audio làm thông điệp và phát lại cho caller ở một module khác. Trong trường hợp này, tôi sẽ upload tệp tin audio làm lời chào cho hệ thống trả lời tự động (IVR).

Thực hiện như sau:

Mở Admin → System Recordings → Add Recording

Sau đó vào các thông tin sau:

  • Phần Name & Description đặt tên và mô tả phù hợp cho thông điệp sẽ phát. Chẳng hạn phát thông điệp lời chào và hướng dẫn nhấn phím để truy cập bộ phận .. Ở đây, tôi đặt greeting.
  • File List for english: Chúng ta có thể browser hoặc kéo tệp tin audio đã có sẵn với một số định dạng như waw, law, ..

Note:

Ở đây, chúng ta có thể sử dụng nhiều tệp tin audio cho một System Recording. Nó sẽ phát lần lượt từng tệp audio theo thứ tự từ trên xuống.

Đường dẫn lưu tệp tin audio mặc định là /var/lib/asterisk/sounds/en/custom

add-new-system-recording

Cuối cùng nhấn Submit → Apply Config để tạo một system recording.

Step2: Tạo IVR

Module IVR cho phép tạo các hệ thống trả lời tự động (IVR), từ đó chúng ta có thể điều hướng cuộc gọi từ ngoài vào một trong các IVR này.

Thực hiện tạo IVR như sau:

Mở Applications → IVR → Add IVR

Sau đó vào các thông tin sau:

  • Phần IVR Name và IVR Description đặt tên và mô tả cho tạo một IVR phù hợp. Ở đây, tôi đặt tên một IVR là Greeting IVR
  • Announcement: Chọn thông điệp sẽ phát. Ở đây chúng ta sẽ chọn greeting mà đã tạo ở System Recordings trong Step1.
  • Enable Direct Dial: Enabled tùy chọn này để phép caller có thể dial đến một extension trong khi đang nghe phát một thông điệp (Tức là có thể dial extension như 100 mà không cần nhấn phím một phím để gặp bộ phận xxx nào đó). Nếu không cho phép thực hiện dial extension như vậy thì chọn tùy chọn Disabled
  • Timeout: Thiết lập lượng thời gian (second) mà hệ thống sẽ người gọi quay số. Sau khoảng thời gian này, nếu người gọi không thực hiện quay số thì hệ thống thực hiện một số tùy chọn tiếp theo.
  • Invalid Retries: Thiết lập số lần cho phép người gọi chọn lại phím số khi nhấn sai phím cần chuyển hướng đến số extension. (ví dụ chỉ thiết lập số 1 gọi đến 101, nhưng người gọi nhấn phím 2 sẽ là phím sai, yêu cầu thực hiện lại).

add-ivr

Tiếp đó trong phần IVR Entries, chúng thiết lập các phím dial tùy chọn để hệ thống direct đến extension phù hợp

  • Digits: Chọn phím để nhấn (ví dụ nhấn phím 1 để direct)
  • Destination: Chọn tùy chọn Extensions và chọn extension phù hợp( chẳng hạn 100 KeepWalking)

Tiếp tục nhấn Add Another Entry để thêm phím khác

add-ivr-02

Sau đó thực hiện nhấn Submit → Apply Config

Step3: Cấu hình Inbound Routes

Sau khi tạo xong Step1 và Step2, chúng ta thực hiện định tuyến Inbound để cho phép người gọi vào hệ thống tổng đài và chuyển vào IVR.
Trong phần trước, chúng ta đã hướng dẫn cấu hình Inbound Routes. Phần này, chúng ta edit lại phần Inbound Routes đó.

inbound-routes-ivr

Mở Connectivity → Inbound Routes → Chọn một Inbound Route và thực hiện chỉnh sửa

inbound-routes-ivr

  • Set Destination: Thiết lập đích route là IVR và chọn tên IVR là Greeting IVR đã tạo ở Step2

Cuối cùng nhấn Submit → Apply Config

1. Về Asterisk

Asterisk là phần mềm dùng làm tổng đài điện thoại – Private Branch Excahnge (PBX). Kết hợp với các giao diện phần cứng điện thoại phù hợp và các ứng dụng mạng, Asterisk được sử dụng để thiết lập và kiểm soát các cuộc gọi giữa các điểm cuối viễn thông, cho phép thực hiện các cuộc gọi nội bộ với nhau, hoặc kết nối với với hệ thống mạng điện thoại chuyển mạch công cộng – Public switched telephone network (PSTN) và các thiết bị hoặc dịch vụ thoại qua mạng IP (VoIP).

Asterisk hỗ trợ nhiều chuẩn giao thức của VoIP như SIP và H.323, MGCP. Nó có thể hoạt động như trạm kết nối giữa các IP phone và mạng PSTN qua giao diện T- hoặc E-carrier hoặc card analog FXO.

Asterisk ra đời vào năm 1999 bởi Mark Spencer, hiện nay thì nó được phát triển bởi Sangoma Technologies Corporation.

Asterisk là phần mềm nguồn mở và nó có thể chạy trên nhiều nền tảng OS như Linux, BSD, MacOS, ..

Mô hình giải pháp tổng đài Asterisk

asterisk

Một số tính năng chính của Asterisk:

  • Voicemail: Tính năng cho phép thực hiện thư thoại. Khi điện thoại bận thì asterisk định hướng cuộc gọi đến hộp thư thoại tương ứng đã khai báo trước

  • IVR (Interactive Voice Response): Được dùng để chỉ chức năng tương tác thoại (tổng đài trả lời tự động).

  • Conference calling: Tính năng cho phép cuộc gọi đàm thoại giữa nhiều người, và có thể thiết lập người nhận cuộc gọi chỉ có thể nghe và không có thể nói.

  • Automated Call Distribution: Hệ thống sẽ tự động phân phối cuộc gọi phù hợp với tương tác của người dùng đối với hệ thống.

  • Call Forwarding: Tính năng chuyển hướng cuộc gọi khi máy đang bận hoặc không trả lời

2. FreePBX Distro

Trước đây, việc xây dựng hệ thống tổng đài Asterisk được thực hiện thủ công với các bước sau:

  • Dựng hệ điều hành phù hợp (Thường là linux như CentOS)
  • Download, cài đặt và cấu hình Asterisk trên OS. Việc cấu hình Asterisk được thao tác trên từng tệp tin.

  • Cài đặt và tích hợp gói DAHDI (Zaptel) để cho phép Asterisk giao tiếp với điện thoại analog hoặc hệ thống PSTN

Việc thao tác nhiều công việc thủ công như vậy chiếm rất nhiều thời gian và dễ xảy ra sai xót. Vì vậy mà hiện nay, nhiều bản distro ra đời mà tích hợp đầy đủ các thành phần của việc xây dựng hệ thống tổng đài như OS, Asterisk, Giao diện, DAHDI và nhiều gói hỗ trợ khác, giúp cho việc triển khai được nhanh chóng và chính xác hơn.

Một số bản distro Asterisk phổ biến hiện nay:

  • Elastix – Debian Linux Asterisk Distribution
  • PBXinaflash – Linux PBX

  • FreePBX – Based on CENTOS – most module require payment

FreePBX Distro là bản OS dựa trên CentOS, gồm giao diện đồ họa (FreePBX) cho cấu hình và quản lý Assterisk. FreePBX Distro gồm các gói cài đặt mà cung cấp các tính năng như VoIP, PBX, Fax, IVR, Voicemail.

3. Về mô hình GSM Gateway và FreePBX

Với doanh nghiệp mà có bộ phận chăm sóc khách hàng đông, với nhu cầu thực hiện nhiều cuộc gọi, khi đó yêu cầu đặt ra là:

  • Có thể sử dụng gọi nội bộ mà không mất chi phí
  • Có thể thực hiện được cuộc gọi trên IP phone, mobile, PC qua mạng

  • Tiết kiệm chi phí cuộc gọi ra ( nghĩa là gọi số của nhà mạng nào thì tự động định tuyến qua SIM của nhà mạng đó)

  • Khi một người trong hệ thống bận hoặc không trả lời, người khác có thể thực hiện nhận cuộc gọi đó.

  • Lưu trữ ghi âm cuộc gọi tập trung

Khi đó, mô hình hệ thống tổng đài IP (IP PBX) kết hợp GSM Gateway ra đời cho phép đáp ứng các yêu cầu trên.

gsm-freepbx

GSM Gateway là gì?

GSM Gateway là thiết bị mà dùng kết nối giữa tổng đài VoIP

GSM Gateway là thiết bị dùng để định tuyến trực tiếp giữa các mạng IP, digital, analog và GSM. Ý tưởng cốt lõi chính của GSM Gateway là tiết kiệm chi phí dựa trên giao thức định tuyến giá thấp nhất (Tiếng Anh là Least Cost Routing – LCR). Bởi vì các thẻ sim và các module GSM được tích hợp trong GSM Gateway, khi đó cuộc gọi sẽ được thực hiện từ GSM đến GSM, thay vì thực hiện từ IP đến GSM, vì vậy mà giá tiền cuộc gọi sẽ rẻ hơn. Ngoài ra, với giao thức LCR, cuộc gọi qua GSM Gateway sẽ được kết nối đến cùng nhà mạng với người nhận cuộc gọi (ví dụ Viettel gọi Viettel, Mobifone gọi Mobifone, ..) vì vậy mà chi phí sẽ thấp nhất.

Các GSM Gateway thường có các tính năng như sau:

  • Cho phép kết nối với các tổng đài IP
  • Sử dụng với các nhà mạng như Viettel, Mobifone, Vinaphone, Gphone…

  • Tự động định tuyến số điện thoại gọi ra theo nhà mạng (nghĩa là gọi số của nhà mạng nào thì tự động định tuyến qua SIM của nhà mạng đó)

  • Cho phép giới hạn thời gian mỗi cuộc gọi, thời gan của mỗi sim

  • Hiển thị trạng thái cuộc gọi đi, đến

Ngoài ra, một số GSM còn hỗ trợ API cho phép kết nối từ các phần mềm cho thông tin về các cuộc gọi, như sử dụng cho CRM, …

1. Về nginx-rtmp module

Nginx-rtmp là module mở rộng, mà kết hợp với Nginx để cho phép xây dựng máy chủ streaming media.

Một số tính năng mà nginx-rtmp hỗ trợ:

  • RTMP/HLS/MPEG-DASH live streaming

  • RTMP Video on demand FLV/MP4, phát từ local file hoặc qua HTTP

  • Stream relay support for distributed streaming: push & pull models

  • Ghi streams vào nhiều tệp FLV

  • Hỗ trợ H264/AAC

  • Transcode trực tuyến với FFmpeg

  • HTTP callbacks (publish/play/record/update etc)

  • Module điều khiển HTTP để recording audio/video and dropping clients

  • Kỹ thuật buffer tiên tiến để giữ cho bộ nhớ được cấp ở mức thấp nhất mà streaming vẫn nhanh.

  • Kết hợp được với các ứng dụng như Wirecast, FMS, Wowza, JWPlayer, FlowPlayer, StrobeMediaPlayback, ffmpeg, avconv, rtmpdump, flvstreamer, ..

  • Thống kê stream với định dạng XML/XSL

  • Linux/FreeBSD/MacOS/Windows

2. Cài đặt Nginx với module nginx-rtmp

Step1: Download & unpack latest stable nginx & nginx-rtmp version

cd /opt
sudo git clone git://github.com/arut/nginx-rtmp-module.git
sudo wget http://nginx.org/download/nginx-1.14.1.tar.gz
sudo tar xzf nginx-1.14.1.tar.gz
mv nginx-1.14.1 nginx

Step2: Build nginx với nginx-rtmp

sudo ./configure --prefix=/etc/nginx \
--pid-path=/var/run/nginx.pid \
--conf-path=/etc/nginx/nginx.conf \
--sbin-path=/usr/sbin/nginx \
--user=nginx \
--group=nginx \
--with-file-aio \
--with-http_ssl_module \
--add-module=nginx-rtmp-module
sudo make
sudo make install

Step3: Run Nginx với systemd

  • Create tệp /lib/systemd/system/nginx.service với nội dung sau:
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID

[Install]
WantedBy=multi-user.target
  • Start Nginx service
systemctl enable nginx.service
systemctl start nginx.service

3. VOD qua RTMP

Chúng ta sẽ cấu hình để cho phép các video player xem video qua giao thức RTMP.

3.1 Cấu hình Nginx

Step1: Tạo tệp tin cấu hình nginx với nội dung sau:

user  nginx;
worker_processes  1;
pid        /run/nginx.pid;
user nginx;

events {
    worker_connections  1024;
}
rtmp {
    server {
        listen 1935;
        chunk_size 4000;
        # video on demand for mp4 files
        application vod {
            play /var/mp4s;
        }
    }
}

http {
    access_log /var/log/nginx/access-streaming.log;
    error_log /var/log/nginx/error-streaming.log;
    server {
        listen      80;
        root /var/www/html;
        # RTMP statistics in XML
        location /stat {
            # Copy stat.xsl put to root directory
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
    }
}

Thông tin cấu hình tệp cấu như sau:

Khối rtmp { }

  • listen port với 1935 (port default)

  • application với đường dẫn ảo là vod

  • Đường dẫn thư mục chứa các tệp video để phát là “/var/mp4s”.

Khi đó muốn sử dụng chúng ta truy cập kiểu như “rtmp://192.168.10.113:1935/vod/video-name.mp4”

Trong đó: Địa chỉ 192.168.10.113 là địa chỉ streaming server mà chúng ta sẽ sử dụng trong bài viết này.

Step2: Tạo thư mục chứa và copy tệp tin video

mkdir /var/mp4s
cd /var/mp4s

Chúng ta download hoặc copy một tin video vào thư mục /var/mp4s

3.2. Sử dụng Video Player để chạy video

Chúng ta có thể sử dụng một trình phát video có hỗ trợ giao thức rtmp để phát.

Ở đây, chúng ta có thể sử dụng VLC player

Mở player VLC → Nhấn Media → Chọn “Open Network Stream ..”. Sau đó vào thông tin đường dẫn tệp video vod với rtmp://192.168.10.113:1935/vod/vod.mp4

vlc-rtmp

Cuối cùng nhấn Play để phát video.

vlc-play

4. VOD qua HLS

Chúng ta sẽ cấu hình để cho phép video player phát video qua giao thức HLS (Apple HTTP Live Streaming).

4.1 Cài đặt Ffmpeg

Sử dụng script Installing FFmpeg on Linux

Nếu chỉ sử dụng một thư viện có sẵn thì cài đặt đơn giản như sau trên CentOS

yum install ffmpeg ffmpeg-devel ffmpeg-libpostproc

Trong phần Cài đặt FFmpeg,  cũng đã giới thiệu và cách sử dụng cơ bản FFmpeg.

4.2 Convert tệp vod.mp4 sang HLS

Trước khi convert, chúng ta thực hiện copy/download tệp tin video lên server (ví dụ tệp tin là vod.mp4)

Sử dụng lệnh ffmpeg để convert vod.mp4 sang định dạng HLS (Apache HTTP Live Stream)

ffmpeg -i video.mp4 -profile:v baseline -level 3.0 -s 720x400 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls /tmp/index.m3u8

Trong đó:

  • vod.mp4 là tệp video đầu vào cần convert

  • index.m3u8 là tệp tin master đầu ra của HLS playlist

  • và một số tham số tùy chọn cho độ phân giải, thời gian phân đoạn, ..

4.3 Cấu hình nginx

Ở đây, Chúng ta sẽ cấu hình nginx làm web server, đồng thời cấu hình làm media server.

user nginx;
worker_processes  1;
error_log  logs/rtmp_error.log debug;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    #serve the player for HLS
    server {
        listen       80;
        root /var/www/html;
        server_name  localhost;
        location /hls {
            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';
            # Allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            add_header Cache-Control no-cache;
            alias /tmp;
        }
    }
}
  • Listen với port default 80

  • URL của web server sẽ là http://192.168.10.113/; với root directory là /var/www/html

  • URL của stream server sẽ là http://192.168.10.113/hls

  • Playlist của stream là tệp tin m3u8, với các segment là tệp ts

  • Đường dẫn thư mục chứa các playlist là /tmp

4.4 Phát video trên web browser với videojs

Chúng ta có thể phát video trên web browser, mà sử dụng flash player như Flowplayer hay Jwplayer. Trong trường hợp này, tôi sẽ giới thiệu sử dụng videojs player cho phát video trên web browser.

Link về videojs: https://github.com/videojs/http-streaming

Trên Nginx web server, chúng ta sẽ tạo tệp tin index.html vào root directory:

Download mẫu tệp index.html

Trong tệp index.html chúng ta sẽ vào đường dẫn chứa tệp tin playlist mà đã convert ở Step2. Khi đó vào thông tin đường dẫn URL ở đây là http://192.168.10.113/hls/index.m3u8

Cuối cùng duyệt http://192.168.10.113/index.html và xem kết quả

bbb-video

Chúng ta thấy videojs cho khung nhìn tuyệt đẹp.

5. Cấu hình Live Streaming

Live Streaming là tính năng chính của nginx-rtmp module, và quá trình thực hiện live streaming sẽ qua giao thức RTMP.

Các bước cho thực hiện quá trình Live Streaming như sau:

5.1 Cấu hình Nginx để làm live streaming server

Step1: Tạo tệp tin nginx.conf với nội dung sau

user nginx;
pid /var/run/nginx.pid;
events {
    worker_connections 1024;
}
#RTMP configuration
rtmp {
    server {
        listen 1935; 
        application live {
            live on;
            # Push the stream to the local HLS application
            push rtmp://localhost:1935/hls;
        }
    
        application hls {
            live on; 
            # Only accept publishing from localhost.
            allow publish 127.0.0.1;
            deny publish all;            
            # Streams as HLS
            hls on;
            hls_path /tmp/hls;
            hls_fragment 3s;
            hls_nested on;
            hls_fragment_naming system;
        }
    }
}

#HTTP Configuration
http {
    sendfile off;
    tcp_nopush on;
    aio on;
    directio 512;
    default_type application/octet-stream;
    server {
        listen 80;
        root /var/www/html;
        server_name localhost;
        location /hls {
            # Disable cache
            add_header 'Cache-Control' 'no-cache';
            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length
            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
            # MIME type for HLS
            types {
                application/dash+xml mpd;
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            alias /tmp/hls;
        }
        # RTMP statistics in XML
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
    }
}

Ở đây, chúng ta sẽ cấu hình nginx làm nhiệm vụ là web server và live streaming server.

  • Block http { } : Dựng nginx làm web server với mục đích thống kê số liệu, cho phép người dùng xem live streaming. Nếu không cần dùng các chức năng này, chúng ta có thể qua bỏ block này. Quá trình tạo server cho xem live streaming có thể thực hiện ở server khác.

  • Block rtmp { } : Dựng nginx làm live streaming server, để thực hiện quá trình thu phát live streaming từ client và publish luồng

Diễn giải một số directive cho cấu hình nginx trên như sau:

  • live on: Bật tính năng live stream.

  • push rtmp://localhost:1935/hls : Thực hiện push streaming vào /hls

  • allow publish 127.0.0.1; Khai báo server từ xa được phép push stream đến hệ thống. Ở đây chúng ta sẽ khai báo localhost được phép push stream đến hệ thống localhost. Kết hợp với deny publish all, nhằm hạn chế remote server nào đó push stream vào hệ thống của mình.

  • deny publish all;

  • hls on: Bật chế độ HLS, cho phép client có thể sử dụng chế độ này

  • hls_path /tmp/hls: Thiết lập đường dẫn thư mục chứa playlist và fragments của HLS. Nếu không chỉ định thì nó tự động tạo.

  • hls_fragment 3s: Thực hiện tạo mỗi fragment với 03 second (fragment *.ts). Thường thì mỗi tệp ts được sinh ra gồm 3s + time decode)

  • hls_nested on; Bật chế độ lồng. Dùng để tạo ra một subdirectory của “hls_path” cho mỗi stream. Playlist và fragments sẽ được tạo ra cùng thư mục đó. Ví dụ /tmp/hls/
    stream-name. Mặc định chế độ này là off, vì vậy stream sẽ tạo ra playlist và fragments ở thư mục của của đường dẫn hls_path, với kiểu tên là stream-name-..ts và stream-name.m3u8

  • hls_fragment_naming system: Tên của fragment, có thể định dạng với các kiểu “system, sequential, timestamp”

Step2: Tạo thư mục và copy tệp statistics dạng xml

mkdir /tmp/hls
chown -R nginx:nginx
copy /opt/nginx/nginx-rtmp-module/stat.xsl /var/www/html
systemctl restart nginx

Step3: Tạo tệp tin index.html

Chúng ta thực hiện tạo tệp tin tĩnh live.html để tạo web player cho xem live streaming qua web browser

Download tệp mẫu tại: live.html

Note: Thay đường dẫn http://192.168.10.113/hls/stream/index.m3u8 với đường dẫn chứa thông tin tệp stream phù hợp.

5.2 Thực hiện live streaming từ mobile

Sử dụng một phần mềm live streaming bất kỳ, hỗ trợ giao thức RTMP. Ở đây, tôi sử dụng android nên cài đặt soft Larix Broadcaster

  • Mở Larix Broadcaster → Nhấn biểu tượng Setting → Connections → Sau đó vào các thông tin kết nối đến Live Streaming server.

rtmp://192.168.10.113:1935/live/stream

(Với tên “stream” là tên bất kỳ do mình đặt. Tên này sau khi lên live server, tương ứng với biến $name)

  • Cuối cùng nhấn vào biểu tượng quay phát để live streaming thôi

5.3 Kiểm tra quá trình Live Streaming

Step1: Xem thông tin tệp streaming trên server

Dùng lệnh để list xem quá trình sinh ra luồng stream với tệp playlist và fragments

list-stream

Step2: Thực hiện xem live stream qua web browser

Mở web browser và truy cập http://192.168.10.113/live.html để xem live streaming

live-streaming-coffee

Step3: Xem thống kê số liệu streaming

Truy cập http://192.168.10.113/stat

streaming-statistics

Một số trang tham khảo