0
点赞
收藏
分享

微信扫一扫

简单分布式系统开发day03

juneyale 2022-01-31 阅读 62

在简单分布式系统day02的基础上,我们增加了一个服务,学生成绩查询服务,
在这里插入图片描述
grades.go代码如下

package grades

import (
	"fmt"
	"sync"
)

type Student struct {
	ID int
	FirstName string
	LastName string
	Grades []Grade
}

func (s Student)Average()float32  {
	var result float32
	for _,grade :=range s.Grades{
		result+=grade.Score
	}
	return result/float32(len(s.Grades))
}

type Students []Student
var (
	students Students
	studentsMutex sync.Mutex
)

func (ss Students)GetByID(id int)(*Student,error)  {
      for i :=range ss{
		  if ss[i].ID == id {
			  return &ss[i], nil
		  }
	  }
	return nil,fmt.Errorf("Student with ID %d not found",id);
}
type GradeType string

const(
	GradeQuiz = GradeType("Quiz")
	GradeTest = GradeType("Test")
	GradeExam = GradeType("Exam")
)
type Grade struct {
	Title string
	Type  GradeType
	Score float32
}

主要功能为定义学生对象的结构体,成绩结构体,通过ID获取某个学生的对象,获取平均值的功能。
mockdata.go代码如下

package grades

func init() {
	students = []Student{
		{
			ID:        1,
			FirstName: "Nick",
			LastName:  "Carter",
			Grades: []Grade{
				{
					Title: "Quiz 1",
					Type:  GradeQuiz,
					Score: 85,
				},
			},
		},
		{
			ID:        2,
			FirstName: "Nick",
			LastName:  "Carter",
			Grades: []Grade{
				{
					Title: "Quiz 1",
					Type:  GradeQuiz,
					Score: 85,
				},
			},
		},
	}
}

手动给students赋值,同时当grades包被调用时,会自动执行init函数
server.go代码内容如下

package grades

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
)

func RegisterHandlers()  {
	handler:=new(studentsHandler)
	http.Handle("/students",handler)
	http.Handle("/students/",handler)

}

type studentsHandler struct {}
// /students
// /students/{id}
// /student/{id}/grades
func (sh studentsHandler)ServeHTTP(w http.ResponseWriter,r *http.Request)  {
	pathSegments :=strings.Split(r.URL.Path,"/")
	switch len(pathSegments) {
	case 2:
		sh.getAll(w,r)
	case 3:
		id,err :=strconv.Atoi(pathSegments[2])
		if err!=nil{
			w.WriteHeader(http.StatusNotFound)
			return
		}
		sh.getOne(w,r,id)
	case 4:
		id,err :=strconv.Atoi(pathSegments[2])
		if err!=nil{
			w.WriteHeader(http.StatusNotFound)
			return
		}
		sh.addGrade(w,r,id)
	default:
		w.WriteHeader(http.StatusNotFound)
	}
}
func (sh studentsHandler) getAll(w http.ResponseWriter,r *http.Request){
	studentsMutex.Lock()
	defer studentsMutex.Unlock()
	data,err :=sh.toJSON(students)
	if err!=nil{
		w.WriteHeader(http.StatusInternalServerError)
		log.Println(err)
		return
	}
	w.Header().Add("Content-Type","application/json")
	w.Write(data)
}
func (sh studentsHandler) getOne(w http.ResponseWriter,r *http.Request,id int){
	studentsMutex.Lock()
	defer studentsMutex.Unlock()
	student,err :=students.GetByID(id)
	if err!=nil{
		w.WriteHeader(http.StatusNotFound)
		log.Println(err)
		return
	}
	data,err :=sh.toJSON(student)
	if err!=nil{
		w.WriteHeader(http.StatusInternalServerError)
		log.Printf("Failed to serialize student:%q",err)
		return
	}
	w.Header().Add("Content-Type","application/json")
	w.Write(data)
}

func (sh studentsHandler)addGrade(w http.ResponseWriter,r *http.Request,id int){
	studentsMutex.Lock()
	defer studentsMutex.Unlock()
	student,err :=students.GetByID(id)
	if err!=nil{
		w.WriteHeader(http.StatusNotFound)
		log.Println(err)
		return
	}
	var g Grade
	dec:=json.NewDecoder(r.Body)
	err =dec.Decode(&g)
	if err!=nil  {
		w.WriteHeader(http.StatusBadRequest)
		log.Println(err)
		return
	}
	student.Grades = append(student.Grades,g)
	w.WriteHeader(http.StatusCreated)
	data,err:=sh.toJSON(g)
	if err!=nil{
		log.Println(err)
		return
	}
	w.Header().Add("Content-Type","application/json")
	w.Write(data)
}

func (sh studentsHandler) toJSON(obj interface{})([]byte,error)  {
	var b bytes.Buffer
	enc:=json.NewEncoder(&b)
	err:=enc.Encode(obj)
	if err!=nil{
		return nil,fmt.Errorf("Failed to serialize students:%s",err)
	}
	return b.Bytes(),nil
}

实现serveHTTP接口,成为一个handle,有获取所有student的方法,获取单个student的方法,还有添加成绩的方法
registration.go

package registry
type  Registration struct {
	ServiceName ServiceName
	ServiceURL string
}
type ServiceName string
const(
	LogService = ServiceName("LogService")
	GradingService = ServiceName("GradingService")

)

gradingservice.go内容

package gradingservice

import (
	"context"
	"distributed/grades"
	"distributed/registry"
	"distributed/service"
	"fmt"
	stlog "log"
)

func main() {
	host,port:="localhost","6000"
	serviceAddress:=fmt.Sprintf("http://%v:%v",host,port)
	r :=registry.Registration{
		ServiceName: registry.GradingService,
		ServiceURL: serviceAddress,
	}
	ctx,err:= service.Start(
		context.Background(),//创建上下文对象
		host,
		port,
		r,
		grades.RegisterHandlers,
	)
	if err!=nil{
		stlog.Fatalln(err)
	}
	<-ctx.Done()
	fmt.Println("shutting down grading service.")
}

主要用于分配响应的handle,启动和监听服务,注册服务.

举报

相关推荐

web开发day03

后台管理系统----day03

day03

Day03

Day03(

Linux Day03

0 条评论