• 
    

      <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
      1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>

        基于KnativeServerless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)

        基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù),相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

        成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的松原網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

        短網(wǎng)址顧名思義就是使用比較短的網(wǎng)址代替很長(zhǎng)的網(wǎng)址。維基百科上面的解釋是這樣的:

        短網(wǎng)址又稱(chēng)網(wǎng)址縮短、縮短網(wǎng)址、URL 縮短等,指的是一種互聯(lián)網(wǎng)上的技術(shù)與服務(wù),此服務(wù)可以提供一個(gè)非常短小的 URL 以代替原來(lái)的可能較長(zhǎng)的URL,將長(zhǎng)的 URL 位址縮短。用戶(hù)訪(fǎng)問(wèn)縮短后的 URL 時(shí)通常將會(huì)重定向到原來(lái)的長(zhǎng) URL

        起源

        雖然現(xiàn)在互聯(lián)網(wǎng)已經(jīng)非常發(fā)達(dá)了,但還是有很多場(chǎng)景會(huì)對(duì)用戶(hù)輸入的內(nèi)容有長(zhǎng)度限制。比如 :

        • 微薄、Twitter 長(zhǎng)度不能超過(guò) 140 個(gè)字

        • 一些早期的 BBS 文章單行的長(zhǎng)度不能超過(guò) 78 字符等場(chǎng)景

        • 運(yùn)營(yíng)商短信的長(zhǎng)度不能超過(guò) 70 個(gè)字

        而現(xiàn)在很多媒體、電商平臺(tái)的內(nèi)容大多都是多人協(xié)作通過(guò)比較復(fù)雜的系統(tǒng)、框架生成的,鏈接長(zhǎng)度幾十個(gè)甚至上百字符都是很平常的事情,所以如果在上述的幾個(gè)場(chǎng)景中傳播鏈接使用短網(wǎng)址服務(wù)就是一個(gè)必然的結(jié)果。比如下面這些短信截圖你應(yīng)該不會(huì)陌生:<br /> 基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)

        應(yīng)用場(chǎng)景

        短網(wǎng)址服務(wù)的最初本意就是縮短長(zhǎng) url,方便傳播。但其實(shí)短網(wǎng)址服務(wù)還能做很多其他的事情。比如下面這些:

        • 訪(fǎng)問(wèn)次數(shù)的限制,比如只能訪(fǎng)問(wèn) 1 次,第二次訪(fǎng)問(wèn)的時(shí)候就拒絕服務(wù)

        • 時(shí)間的限制,比如只能在一周內(nèi)提供訪(fǎng)問(wèn)服務(wù),超過(guò)一周就拒絕服務(wù)

        • 根據(jù)訪(fǎng)問(wèn)者的地域的限制

        • 通過(guò)密碼訪(fǎng)問(wèn)

        • 訪(fǎng)問(wèn)量統(tǒng)計(jì)

        • 高峰訪(fǎng)問(wèn)時(shí)間統(tǒng)計(jì)等等

        • 統(tǒng)計(jì)訪(fǎng)問(wèn)者的一些信息,比如:

          • 來(lái)源城市

          • 訪(fǎng)問(wèn)時(shí)間

          • 使用的終端設(shè)備、瀏覽器

          • 訪(fǎng)問(wèn)來(lái)源 IP

        • 在營(yíng)銷(xiāo)活動(dòng)中其實(shí)還可以對(duì)不同的渠道生成不通的短網(wǎng)址,這樣通過(guò)統(tǒng)計(jì)這些短網(wǎng)址還能判斷不同渠道的訪(fǎng)問(wèn)量等信息

        基于 Knative Serverless 技術(shù)實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)

        在 Knative 模式下可以實(shí)現(xiàn)按需分配,沒(méi)有流量的時(shí)候?qū)嵗s容到零,當(dāng)有流量進(jìn)來(lái)的時(shí)候再自動(dòng)擴(kuò)容實(shí)例提供服務(wù)。<br />現(xiàn)在我們就基于阿里云容器服務(wù)的 Knative 來(lái)實(shí)現(xiàn)一個(gè) serverless 模式的短網(wǎng)址服務(wù)。本示例會(huì)給出一個(gè)完整的 demo,你可以自己在阿里云容器服務(wù)上面創(chuàng)建一個(gè) Knative 集群,使用本示例提供服務(wù)。本示例中實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的功能

        • 通過(guò)接口實(shí)現(xiàn)長(zhǎng)網(wǎng)址到短網(wǎng)址的映射服務(wù)

        • 當(dāng)用戶(hù)通過(guò)瀏覽器訪(fǎng)問(wèn)短網(wǎng)址的時(shí)候通過(guò) 301 跳轉(zhuǎn)到長(zhǎng)網(wǎng)址

        下面我們一步一步實(shí)現(xiàn)這個(gè)功能

        數(shù)據(jù)庫(kù)

        既然要實(shí)現(xiàn)短網(wǎng)址到長(zhǎng)網(wǎng)址的映射,那么就需要保存長(zhǎng)網(wǎng)址的信息到數(shù)據(jù)庫(kù),并且生成一個(gè)短的 ID 作為短網(wǎng)址的一部分。所以我們首先需要選型使用什么數(shù)據(jù)庫(kù)。在本示例中我們選擇使用阿里云的表格存儲(chǔ),表格存儲(chǔ)最大的優(yōu)勢(shì)就是按量服務(wù),你只需要為你使用的量付費(fèi),而且價(jià)格也很實(shí)惠。如下所示的按量計(jì)費(fèi)價(jià)格表。1G 的數(shù)據(jù)保存一年的費(fèi)用是3.65292元/年( 0.000417 _ 24 _ 365=3.65292) ,是不是很劃算。

        基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)

        短網(wǎng)址生成 API

        我們需要有一個(gè) API 生成短網(wǎng)址

        /new?origin-url=${長(zhǎng)網(wǎng)址}

        • origin-url 訪(fǎng)問(wèn)地址

        返回結(jié)果

        vEzm6v

        假設(shè)我們服務(wù)的域名是 short-url.default.serverless.kuberun.com ,那么現(xiàn)在訪(fǎng)問(wèn) http://short-url.default.serverless.kuberun.com/vEzm6v 就可以跳轉(zhuǎn)到長(zhǎng)網(wǎng)址了。

        代碼實(shí)現(xiàn)

        package main
        
        import (
        	"crypto/md5"
        	"encoding/hex"
        	"fmt"
        	"log"
        	"net/http"
        	"os"
        	"strconv"
        	"time"
        
        	"strings"
        
        	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
        )
        
        var (
        	alphabet = []byte("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
        	l        = &Log{}
        )
        
        func ShortUrl(url string) string {
        	md5Str := getMd5Str(url)
        	var tempVal int64
        	var result [4]string
        	for i := 0; i < 4; i++ {
        		tempSubStr := md5Str[i*8 : (i+1)*8]
        		hexVal, _ := strconv.ParseInt(tempSubStr, 16, 64)
        		tempVal = 0x3FFFFFFF & hexVal
        		var index int64
        		tempUri := []byte{}
        		for i := 0; i < 6; i++ {
        			index = 0x0000003D & tempVal
        			tempUri = append(tempUri, alphabet[index])
        			tempVal = tempVal >> 5
        		}
        		result[i] = string(tempUri)
        	}
        	return result[0]
        }
        
        func getMd5Str(str string) string {
        	m := md5.New()
        	m.Write([]byte(str))
        	c := m.Sum(nil)
        	return hex.EncodeToString(c)
        }
        
        type Log struct {
        }
        
        func (log *Log) Infof(format string, a ...interface{}) {
        	log.log("INFO", format, a...)
        }
        
        func (log *Log) Info(msg string) {
        	log.log("INFO", "%s", msg)
        }
        
        func (log *Log) Errorf(format string, a ...interface{}) {
        	log.log("ERROR", format, a...)
        }
        
        func (log *Log) Error(msg string) {
        	log.log("ERROR", "%s", msg)
        }
        
        func (log *Log) Fatalf(format string, a ...interface{}) {
        	log.log("FATAL", format, a...)
        }
        
        func (log *Log) Fatal(msg string) {
        	log.log("FATAL", "%s", msg)
        }
        
        func (log *Log) log(level, format string, a ...interface{}) {
        	var cstSh, _ = time.LoadLocation("Asia/Shanghai")
        	ft := fmt.Sprintf("%s %s %s\n", time.Now().In(cstSh).Format("2006-01-02 15:04:05"), level, format)
        	fmt.Printf(ft, a...)
        }
        
        func handler(w http.ResponseWriter, r *http.Request) {
        	l := &Log{}
        	l.Infof("Hello world received a request, url: %s", r.URL.Path)
        	l.Infof("url:%s ", r.URL)
        	//if r.URL.Path == "/favicon.ico" {
        	//	http.NotFound(w, r)
        	//	return
        	//}
        
        	urls := strings.Split(r.URL.Path, "/")
        	originUrl := getOriginUrl(urls[len(urls)-1])
        	http.Redirect(w, r, originUrl, http.StatusMovedPermanently)
        }
        
        func new(w http.ResponseWriter, r *http.Request) {
        	l.Infof("Hello world received a request, url: %s", r.URL)
        	l.Infof("url:%s ", r.URL)
        	originUrl, ok := r.URL.Query()["origin-url"]
        	if !ok {
        		l.Errorf("no origin-url params found")
        		w.WriteHeader(http.StatusBadRequest)
        		w.Write([]byte("Bad request!"))
        		return
        	}
        
        	surl := ShortUrl(originUrl[0])
        	save(surl, originUrl[0])
        	fmt.Fprint(w, surl)
        
        }
        
        func getOriginUrl(surl string) string {
        	endpoint := os.Getenv("OTS_TEST_ENDPOINT")
        	tableName := os.Getenv("TABLE_NAME")
        	instanceName := os.Getenv("OTS_TEST_INSTANCENAME")
        	accessKeyId := os.Getenv("OTS_TEST_KEYID")
        	accessKeySecret := os.Getenv("OTS_TEST_SECRET")
        	client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
        
        	getRowRequest := &tablestore.GetRowRequest{}
        	criteria := &tablestore.SingleRowQueryCriteria{}
        
        	putPk := &tablestore.PrimaryKey{}
        	putPk.AddPrimaryKeyColumn("id", surl)
        	criteria.PrimaryKey = putPk
        
        	getRowRequest.SingleRowQueryCriteria = criteria
        	getRowRequest.SingleRowQueryCriteria.TableName = tableName
        	getRowRequest.SingleRowQueryCriteria.MaxVersion = 1
        
        	getResp, _ := client.GetRow(getRowRequest)
        	colmap := getResp.GetColumnMap()
        	return fmt.Sprintf("%s", colmap.Columns["originUrl"][0].Value)
        }
        
        func save(surl, originUrl string) {
        	endpoint := os.Getenv("OTS_TEST_ENDPOINT")
        	tableName := os.Getenv("TABLE_NAME")
        	instanceName := os.Getenv("OTS_TEST_INSTANCENAME")
        	accessKeyId := os.Getenv("OTS_TEST_KEYID")
        	accessKeySecret := os.Getenv("OTS_TEST_SECRET")
        	client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)
        
        	putRowRequest := &tablestore.PutRowRequest{}
        	putRowChange := &tablestore.PutRowChange{}
        	putRowChange.TableName = tableName
        
        	putPk := &tablestore.PrimaryKey{}
        	putPk.AddPrimaryKeyColumn("id", surl)
        	putRowChange.PrimaryKey = putPk
        
        	putRowChange.AddColumn("originUrl", originUrl)
        	putRowChange.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
        	putRowRequest.PutRowChange = putRowChange
        
        	if _, err := client.PutRow(putRowRequest); err != nil {
        		l.Errorf("putrow failed with error: %s", err)
        	}
        }
        
        func main() {
        	http.HandleFunc("/", handler)
        	http.HandleFunc("/new", new)
        	port := os.Getenv("PORT")
        	if port == "" {
        		port = "9090"
        	}
        
        	if err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil); err != nil {
        		log.Fatalf("ListenAndServe error:%s ", err.Error())
        	}
        
        }

        代碼我已經(jīng)編譯成鏡像,你可以直接使用 registry.cn-hangzhou.aliyuncs.com/knative-sample/shorturl:v1 此鏡像編部署服務(wù)。

        三步走起?。?!

        第一步 準(zhǔn)備數(shù)據(jù)庫(kù)

        首先到阿里云開(kāi)通表格存儲(chǔ)服務(wù),然后創(chuàng)建一個(gè)實(shí)例和表。我們需要的結(jié)構(gòu)比較簡(jiǎn)單,只需要短 URL ID 到長(zhǎng) URL 的映射即可,存儲(chǔ)表結(jié)構(gòu)設(shè)計(jì)如下:

        名稱(chēng)描述
        id短網(wǎng)址 ID
        originUrl長(zhǎng)網(wǎng)址

        第二步 獲取 access key

        登陸到阿里云以后鼠標(biāo)浮動(dòng)在頁(yè)面的右上角頭像,然后點(diǎn)擊 accesskeys 跳轉(zhuǎn)到 accesskeys 管理頁(yè)面<br /> 基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù) <br />點(diǎn)擊顯示即可顯示 Access Key Secret<br /> 基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)

        第三步 部署服務(wù)

        Knative Service 的配置如下, 使用前兩步的配置信息填充 Knative Service 的環(huán)境變量。然后部署到 Knative集群即可

        apiVersion: serving.knative.dev/v1alpha1
        kind: Service
        metadata:
          name: short-url
          namespace: default
        spec:
          template:
            metadata:
              labels:
                app: short-url
              annotations:
                autoscaling.knative.dev/maxScale: "20"
                autoscaling.knative.dev/minScale: "0"
                autoscaling.knative.dev/target: "100"
            spec:
              containers:
                - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/shorturl:v1
                  ports:
                    - name: http1
                      containerPort: 8080
                  env:
                  - name: OTS_TEST_ENDPOINT
                    value: http://t.cn-hangzhou.ots.aliyuncs.com
                  - name: TABLE_NAME
                    value: ${TABLE_NAME}
                  - name: OTS_TEST_INSTANCENAME
                    value: ${OTS_TEST_INSTANCENAME}
                  - name: OTS_TEST_KEYID
                    value: ${OTS_TEST_KEYID}
                  - name: OTS_TEST_SECRET
                    value: ${OTS_TEST_SECRET}

        使用上面的 knative service 部署服務(wù),部署好以后可能是下面這樣:

        └─# kubectl get ksvc
        short-url       http://short-url.default.serverless.kuberun.com       short-url-456q9       short-url-456q9       True

        現(xiàn)在可以開(kāi)始測(cè)試

        • 生成一個(gè)短網(wǎng)址

        └─# curl 'http://short-url.default.serverless.kuberun.com/new?origin-url=https://help.aliyun.com/document_detail/121534.html?spm=a2c4g.11186623.6.786.41e074d9oHpbO2'
        vEzm6v

        curl 命令輸出的結(jié)果 VR7baa 就是短網(wǎng)址的 ID

        • 訪(fǎng)問(wèn)短網(wǎng)址<br /> 在瀏覽器中打開(kāi) http://short-url.default.serverless.kuberun.com/vEzm6v 就能跳轉(zhuǎn)到長(zhǎng) url 網(wǎng)址了。

        本實(shí)戰(zhàn)我們只需三步就基于 Knative 實(shí)現(xiàn)了一個(gè) Serverless 的短網(wǎng)址服務(wù),此短網(wǎng)址服務(wù)在沒(méi)有請(qǐng)求的時(shí)候可以縮容到零節(jié)省計(jì)算資源,在有很多請(qǐng)求的時(shí)候可以自動(dòng)擴(kuò)容。并且使用了阿里云表格存儲(chǔ),這樣數(shù)據(jù)庫(kù)也是按需付費(fèi)?;?Knative + TableStore 實(shí)現(xiàn)了短網(wǎng)址服務(wù)的 Serverless 化。

        看完上述內(nèi)容,你們掌握基于Knative Serverless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

        本文題目:基于KnativeServerless技術(shù)如何實(shí)現(xiàn)一個(gè)短網(wǎng)址服務(wù)
        鏈接分享:http://www.jbt999.com/article18/jjesgp.html

        成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)、虛擬主機(jī)、外貿(mào)建站、面包屑導(dǎo)航、定制開(kāi)發(fā)、域名注冊(cè)

        廣告

        聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

        外貿(mào)網(wǎng)站制作

      2. 
        

          <address id="upfr9"><pre id="upfr9"><strike id="upfr9"></strike></pre></address>
          1. <address id="upfr9"><tr id="upfr9"></tr></address><dl id="upfr9"></dl>
            古典武侠区伊人一区人妻在线 | 国产c一区 | 天堂在线V | a一级片网站 | www.毛片网站 | 免费一级黄色大片 | 色国产在线视频 | 国产乱婬AⅤ片免费 | 五月天成人免费视频 | 操操网站 |