本文介绍如何使用函数计算控制台编写赋予函数公网IP地址的函数。
背景信息
操作步骤
- 登录函数计算控制台。
- 在顶部菜单栏,选择地域。
- 创建函数A。
- 单击服务及函数,在服务及函数页面,单击新增函数。
- 在新增函数页面,将鼠标悬浮于HTTP函数,单击配置部署。
- 设置函数A信息,单击新建。
本示例代码基于Python,因此运行环境选择Python 2.7。
说明 如果输入的服务不存在的话,函数计算会自动创建该服务。 - 在代码执行界面,选择在线编辑,输入以下代码。
-*- coding: utf-8 -*- import logging import urllib, urllib2, sys import ssl import json # 代理服务地址。 proxy_address = 'ip:port' # 函数B服务地址。 data_service_host = 'https://{id}.{region}.fc.aliyuncs.com' data_service_path = '/service/path' def handler(environ, start_response): """ entrance """ url = data_service_host + data_service_path # 使用代理访问。 proxy_result = get_data_by_url(url, proxy_address) # 不使用代理访问。 normal_result = get_data_by_url(url, None) # 用于展示,将两种情况的返回结果拼接后展示出来。 result = { "query_with_proxy_result": proxy_result, "query_without_proxy_result": normal_result } status = '200 OK' response_headers = [('Content-type', 'text/json')] start_response(status, response_headers) return json.dumps(result) def get_data_by_url(url, proxy): """ 用户数据服务访问封装。 """ result = { "success": False, "secret_data": '', "data_service_raw_data": {} } content = my_http_request(url, proxy) if content: content = json.loads(content) result["data_service_raw_data"] = content # 模拟访问后数据处理。 if "authorized" in content and content["authorized"]: result["success"] = True result["secret_data"] = content["protected_data"] return result def my_http_request(url, proxy=None): """ 带Proxy的网络请求。 """ try: ret = None socket_fd = None request = urllib2.Request(url) request.add_header('User-Agent', 'Fake_browser/1.0') if proxy: request.set_proxy(proxy, 'http') opener = urllib2.build_opener() socket_fd = opener.open(request) ret = socket_fd.read() except Exception as e: ret = json.dumps({"info": "exception in proxy query: %s" % e}) finally: if socket_fd: socket_fd.close() return ret
函数说明如下:
handler
为函数调用入口,描述了业务逻辑,本例中分别模拟了不经过代理调用函数B及经过代理调用函数B的调用结果。get_data_by_url
封装了请求函数B数据的业务逻辑。my_http_request
实现了利用代理发送HTTP请求的方式。
- 重复上述步骤创建函数B,在代码执行界面,输入以下代码。说明 函数B使用了Django框架,因此可采用命令行工具fcli或Python SDK上传代码包,您也可以使用OSS或ZIP包直接上传。
函数B代码结构如下:
project/ ├── lib │ ├── Django-1.11.13.dist-info │ ├── django │ ├── pytz │ └── pytz-2018.4.dist-info ├── main.py └── src ├── __init__.py ├── bin │ ├── __init__.py │ └── manage.py ├── conf │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── data └── views ├── __init__.py └── view.py
Django代码示例如下。
- 函数入口:
#!/usr/bin/env python # coding=utf-8 import sys import os # load local django sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + '/lib') sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "src")) import django print (django.__version__) import views.view from conf.wsgi import application def handler(environ, start_response): import urlparse parsed_tuple = urlparse.urlparse(environ['fc.request_uri']) li = parsed_tuple.path.split('/') global base_path if not views.view.base_path: views.view.base_path = "/".join(li[0:5]) return application(environ, start_response)
- urls.py:
from django.conf.urls import url from django.contrib import admin from views import view urlpatterns = [ url(r'^index$', view.index), url(r'^get_data$', view.get_data), ]
- views.py:
#!/usr/bin/env python # coding=utf-8 from django.http import HttpResponse from django.conf import settings import logging import json logger = logging.getLogger() base_path = "" def index(request): """ 测试入口。 """ logger.info("Django request detected! url: index") white_list = settings.WHITE_LIST allowed_hostlist = ' ' for allowed_host in white_list: allowed_hostlist += allowed_host allowed_hostlist += ' ' return HttpResponse("<h1>It works! Copyright: jianyi</h1> White list: %s" % allowed_hostlist, status=200) def get_data(request): """ 数据获取接口。 """ result = { "remote_ip": '', "white_list": [], "authorized": False, "protected_data": '' } if request.META.has_key('HTTP_X_FORWARDED_FOR'): remote_ip = request.META['HTTP_X_FORWARDED_FOR'] else: remote_ip = request.META['REMOTE_ADDR'] result["remote_ip"] = remote_ip result["white_list"] = settings.WHITE_LIST if remote_ip in result["white_list"]: result["authorized"] = True result["protected_data"] = "Alibaba" return HttpResponse(json.dumps(result), status=200)
- settings.py:在默认的settings.py文件结尾增加白名单配置,白名单中添加代理服务器的公网IP地址。
# User conf WHITE_LIST = [ "127.0.0.1", "xx.xx.xx.xx" ]
- 函数入口:
- 配置触发器。具体步骤,请参见创建触发器。
- 搭建并启动Nginx代理。
Nginx可以部署到ECS中,也可以部署到普通服务器上。更多信息,请参见Nginx安装。安装后,您可以按照以下示例配置文件代理部分。
server{ resolver x.x.x.x; listen 8080; location / { proxy_pass http://$http_host$request_uri; } }
注意- 文件代理部分不能包含hostname。
- 需要设置您的DNS服务器IP地址。
$http_host
和$request_uri
为Nginx系统变量,请勿替换。- 在实际生产环境中,我们建议搭建负载均衡集群(利用Nginx、Keepalived 等)及代理服务器集群进行代理服务,以提高系统可用性及整体性能。
在文档使用中是否遇到以下问题
更多建议
匿名提交