服务计算学习之路-开发 web 服务程序

开发 web 服务程序

简介

开发简单 web 服务程序 cloudgo,了解 web 服务器工作原理。

开发环境

  • CentOS7
  • go 1.9.4 linux/amd64

Go的http包

使用http包编写的简单web服务器

下面是一个简单的web服务器,实现在客户端访问http://127.0.0.1:9090/的时候响应内容为Hello World!

package main

import (
    "fmt"
    "net/http"
    "strings"
    "log"
)

func main() {
   
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
   
        w.Write([]byte("Hello World!"))
    })                                       //设置访问的路由
    err := http.ListenAndServe(":9090", nil) //设置监听的端口
    if err != nil {
   
        log.Fatal("ListenAndServe: ", err)
    }
}

从上面的代码可以看到,要编写一个Web服务器很简单,首先调用http.HandleFunc()设置路由和响应处理函数,调用http.ListenAndServe()去监听端口,等待客户端访问即可。那http包又为我们做了什么呢,接下来我将分析一下http包的代码执行流程。

http包源码分析
http包有关路由部分

根据上面代码,首先是调用了http.HandleFunc(),它的定义如下,实现了将传入的处理响应函数与对应的path进行匹配。

// HandleFunc registers the handler function for the given pattern.
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
   
	mux.Handle(pattern, HandlerFunc(handler))
}

所以在Handle()函数中默认的路由是怎样匹配的呢,先看下面的两个struct,它们存放了默认的路由规则

type ServeMux struct {
   
	mu sync.RWMutex   //锁机制,因为请求会涉及到并发处理
	m  map[string]muxEntry  //路由规则,使用map将string对应mux实体,这里的string是注册的路由表达式
	hosts bool        //是否在任意的规则中带有host信息
}
type muxEntry struct {
   
	explicit bool     //是否精确匹配
	h        Handler  //这个路由表达式对应的处理响应函数
	pattern  string   //匹配字符串
}

根据http.HandleFunc()中的代码,执行了mux.Handle(),这个函数对传入的path进行解析,然后向ServeMux中添加路由规则

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
   
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
   
		panic("http: invalid pattern " + pattern)
	}
	if handler == nil {
   
		panic("http: nil handler")
	}
	if mux.m[pattern].explicit {
   
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
   
		mux.m = make(map[string]muxEntry)
	}
    //增加一个新的匹配规则
    mux.m[pattern] = muxEntry{
   explicit: true, h: handler, pattern: pattern}
     
    //根据path的第一个字母判断是否有host
    if pattern[0] != '/' {
   
        mux.hosts = true
    }
 
	// Helpful behavior:
	// If pattern is /tree/, insert an implicit permanent redirect for /tree.
	// It can be overridden by an explicit registration.
	n := len(pattern)
	if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
   
		// If pattern contains a host name, strip it and use remaining
		// path for redirect.
		path := pattern
		if pattern[0] != '/' {
   
			// In pattern, at least the last character is a '/', so
			// strings.Index can't be -1.
			path = pattern[strings.Index(pattern, "/"):]
		}
		url := &url.URL{
   Path: path}
		mux.m[pattern[0:n-1]] = muxEntry{
   h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
	}
}

既然添加了路由规则,那么如果客户端进行访问,是怎样查找到对应的路由规则呢,对过程mux.ServerHTTP->mux.Handler->mux.handler->mux.match进行追踪,找到了路由匹配函数match()。这个函数的实现解释了为什么会匹配最长的最佳匹配,比如传入/user/hh,不是先匹配/user/,而是匹配了/user/hh。

func (mux *ServeMux) match(path string) (h Handler, pattern string) {
   
    var n = 0
    for k, v := range mux.m {
   
        if !pathMatch(k, path) {
   
            continue
        }
        //如果匹配到了一个规则,还会继续匹配并且判断path的长度是否最长
        if h == nil || len(k) > n {
   
            n = len(k)
            h = v.h
            pattern = v.pattern
        }
    }
    return
}
http包有关监听与服务部分

接下来就是执行http.ListenAndServe(),可以发现这个函数首先实例化了Server,接着调用了Server.ListenAndServe()

func ListenAndServe(addr string, handler Handler) error {
   
	server := &Server
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
从1990年代开始,IT的快速发展为传统服务业带来了的巨大的革新并逐步形成了知识经济为主体的现代服务业。同第一产业的农业和第二产业的工业一样,服务业的快速发展也需要相应的理论体系和工程技术加以支持。IBM公司于2004年提出的"服务科学、管理与工程(Service Sciences, Management and Engineering, SSME)",试图将传统的服务相关学科的知识整合起来形成一个称为"服务科学"的独立学科,吸引学术界、教育界和工业界共同关注"服务"的研究与实践, 进而提高服务产业的水平。"服务计算"正是关注服务科学中基础理论、技术体系和工程实践的学科门类,高等学校培养的面向现代服务业的科技型人才必须具备该学科的相关知识及应用能力。作为现代服务科学的奠基石,服务计算已成为一项桥接商业服务与信息技术服务的跨学科的科学技术。IEEE认为服务计算已成为面向现代服务业的一门新的基础学科。服务计算已经成为新兴的系统构造和 企业管理模型,产业界迫切需要掌握服务计算相关理论和技术的软件工程师和管理人员。本课程面对这一需求,涵盖了服务计算方向的主要知识点,主要内容包括服务计算概要、面向服务的体系结构(方法学)、服务计算技术(技术观)、Web服务基础(实现式)、实时服务计算(航空航天特色)和服务计算的基础理论(理论点)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值