Go容器化微服务系统实战

 1-1 本课的go微服务有什么不同?

聚焦于容器化可观测的购物微服务系统实战,通过介绍Go语言的应用趋势、容器化优势及微服务适用性,旨在解决学习微服务过程中遇到的难点。课程内容涵盖微服务整体架构、技术工具框架及容器平台等关键技术,包括API网关层、接口层、应用层及领域层等模块。

 

 

第2章 Go微服务介绍与容器化入门 

2-1 微服务基础介绍

微服务介绍
  1. 微服务首先他是一种架构模式
  2. 微服务相比较单体架构,微服务架构更独立,能够单独更新和发布
  3. 微服务里面的服务仅仅用于某一个特定的业务功能
  4. 特点
    • 逻辑清晰
    • 快速迭代
    • 多语言灵活组合

微服务与DDD
领域驱动设计(Domain Driven Design,简称DDD )
还有个定律:康威定律(Conway’s Law)。就是说组织架构对应我们微服务拆分。
DDD的作用:真正决定软件复杂性的是设计方法
有助于指导我们确定系统边界
能够聚焦在系统核心元素上
帮助我们拆分系统
DDD常用概念-领域
领域:领域是有范围界限的,也可以说是有边界的
核心域:核心域是业务系统的核心价值
通用子域:所有子域的消费者,提供着通用服务(比如电商领域的短信、邮件就属于这个)
支撑子域:专注于业务系统的某一重要的业务
DDD常用概念-界限上下文
理解∶语文中的语境的意思
方式∶领域+界限上下文
目的:不在于如何划分边界,而在于如何控制边界
DDD常用概念-领域模型
理解∶领域模型是对我们软件系统中要解决问题的抽象表达。
领域∶反应的是我们业务上需要解决的问题
模型:我们针对该问题提出的解决方案、

2-2 微服务必备技能Docker入门介绍

 

2-3 go-micro基础之 grpc proto 

 

 

 

2-4 go-micro 组件架构及通讯原理 


2-5 go-micro 入门案例编写


2-6 go-micro 入门案例验证

第3章 微服务模块开发

micro_practice/user at main · yunixiangfeng/micro_practice · GitHub

3-1 micro new 和项目目录创建 

开发目录和依赖包

 项目目录搭建

# 使用容器方式micro/micro 这个容器创建不了--type=api 只能创建service 估计版本问题
sudo docker pull micro/micro
sudo docker run --rm -v $(pwd):$(pwd) -w $(pwd) micro/micro new user(user是我们需要开发的模块)
# 使用容器方式microhq/micro 这个容器暂时用不起来 老报错GOPATH路径找不到 改天研究一下
sudo docker run --rm -v $(pwd):$(pwd) -w $(pwd) microhq/micro new user(user是我们需要开发的模块)
# 直接安装环境 验证micro是否安装成功:micro --version
# 官网https://micro.mu/introduction 这里的最新版本已经不支持consul建议使用etcd
go get github.com/micro/micro
micro new user

 Go module的使用

 GORM基本介绍及使用

3-2 go mod 私有化设置 和 gorm 说明 


3-3 编写proto并自动生成代码

user.proto

syntax = "proto3";

package go.micro.service.user;

service User {
    //注册
    rpc Register(UserRegisterRequest) returns (UserRegisterResponse) {}
    //登录
    rpc Login(UserLoginRequest) returns (UserLoginResponse) {}
    //查询用户信息
    rpc GetUserInfo(UserInfoRequest) returns (UserInfoResponse) {}
}

message UserInfoRequest {
    string user_name = 1;
}

message UserInfoResponse {
    int64 user_id = 1;
    string user_name = 2;
    string first_name = 3;
}

message UserRegisterRequest {
    string user_name = 1;
    string first_name = 2;
    string pwd = 3;
    //... 其它信息
}

message UserRegisterResponse {
    string message = 1;
}

message UserLoginRequest {
    string user_name = 1;
    string pwd = 2;
}

message UserLoginResponse {
    bool is_success = 1;
}

protoc -I ./ --go_out=./ --micro_out=./  ./proto/user/*.proto

3-4 domain对数据库和模型进行操作

D:\Workspace\Go\src\micro_practice\user\domain\service\user_data_service.go
3-5 编写Handel要暴露的服务 

D:\Workspace\Go\src\micro_practice\user\handler\user.go

D:\Workspace\Go\src\micro_practice\user\main.go
3-6 go-micro开发流程梳理 

D:\Workspace\Go\src\micro_practice\user\main.go


3-7 dockerfile 打包 user 功能

D:\Workspace\Go\src\micro_practice\user\Dockerfile

FROM alpine

ADD user /user

ENTRYPOINT [ "/user" ]

D:\Workspace\Go\src\micro_practice\user\Makefile


GOPATH:=$(shell go env GOPATH)
.PHONY: proto
proto:
	sudo docker run --rm -v $(shell pwd):$(shell pwd) -w $(shell pwd) -e ICODE=CF388DF1EF1C5EBE cap1573/cap-protoc -I ./ --go_out=./ --micro_out=./  ./proto/user/*.proto
	
.PHONY: build
build:
	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o user *.go

.PHONY: test
test:
	go test -v ./... -cover

.PHONY: dockerBuild
dockerBuild:
	sudo docker build -t user:latest .

make proto

make build

make dockerBuild

第4章 注册配置中心实现

https://github.com/yunixiangfeng/micro_practice/tree/main/category

4-1 注册中心的基本介绍 

注册中心Consul原理介绍
Consul基本介绍
调用过程原理讲解及集群版本原理

Consul的安装和使用

注册中心Consul基本介绍
Consul是一种服务网格解决方案
提供具有服务发现,配置和分段功能的全功能控制平面
Consul 附带一个简单的内置代理,可以开箱即用

注册中心Consul关键功能
服务发现:客户端可以注册服务,程序可以轻松找到它们所依赖的服务
运行状况检查: Consul 客户端可以提供任意数量的运行状况检查
KV存储:应用程序可以将 Consul 的层级键/值存储用于任何目的包括动态配置,功能标记,协调,领导者选举等

注册中心Consul两个重要协议
Gossip Protocol(八卦协议)
Raft Protocol(选举协议)
4-2 注册中心的安装 

注册中心Consul安装
docker pull cap1573/consu
docker run -d -p 8500:8500 cap1573/consul
Consul web 管理界面简单说明

4-3 分类模块目录结构生成 


4-4 编写对外暴露的服务 

D:\Workspace\Go\src\micro_practice\category\Makefile

GOPATH:=$(shell go env GOPATH)
.PHONY: proto
proto:
	sudo docker run --rm  -v $(shell pwd):$(shell pwd) -w $(shell pwd) -e ICODE=CF388DF1EF1C5EBE cap1573/cap-protoc -I ./ --micro_out=./ --go_out=./ ./proto/category/category.proto

.PHONY: build
build: 

	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o category-service *.go

.PHONY: test
test:
	go test -v ./... -cover

.PHONY: docker
docker:
	docker build . -t category-service:latest

D:\Workspace\Go\src\micro_practice\category\proto\category\category.proto

syntax = "proto3";

package go.micro.service.category;

service Category {
	rpc CreateCategory(CategoryRequest) returns (CreateCategoryResponse) {}
	rpc UpdateCategory(CategoryRequest) returns (UpdateCategoryResponse) {}
	rpc DeleteCategory(DeleteCategoryRequest) returns (DeleteCategoryResponse){}
	rpc FindCategoryByName(FindByNameRequest) returns (CategoryResponse) {}
	rpc FindCategoryByID(FindByIdRequest) returns (CategoryResponse){}
	rpc FindCategoryByLevel(FindByLevelRequest) returns (FindAllResponse) {}
	rpc FindCategoryByParent(FindByParentRequest) returns (FindAllResponse) {}
	rpc FindAllCategory(FindAllRequest) returns (FindAllResponse){}
}

message CategoryRequest {
	string category_name = 1;
	uint32 category_level = 2;
	int64 category_parent = 3;
	string category_image = 4;
	string category_description = 5;
}

message CreateCategoryResponse {
	string message =1 ;
	int64 category_id =2;
}

message UpdateCategoryResponse {
	string message = 1;
}

message DeleteCategoryRequest {
	int64 category_id =1 ;
}

message DeleteCategoryResponse {
	string message =1;
}

message FindByNameRequest {
	string category_name =1;
}

message CategoryResponse {
	int64 id = 1;
	string category_name =2;
	uint32 category_level = 3;
	int64 category_parent =4;
	string category_images =5;
	string category_description =6;
}

message FindByIdRequest {
	int64 category_id = 1;
}

message FindByLevelRequest {
	uint32 level =1;
}

message FindByParentRequest {
	int64 parent_id =1;
}

message FindAllRequest {

}

message FindAllResponse {
	repeated CategoryResponse category =1;
}

protoc -I ./ --micro_out=./ --go_out=./ ./proto/category/category.proto

4-5 数据库进行交互

D:\Workspace\Go\src\micro_practice\category\domain\model\category.go

D:\Workspace\Go\src\micro_practice\category\domain\repository\category_repository.go

D:\Workspace\Go\src\micro_practice\category\domain\service\category_data_service.go


4-6 编写Handler 

D:\Workspace\Go\src\micro_practice\category\handler\category.go
4-7 配置中心/注册中心的使用 

D:\Workspace\Go\src\micro_practice\category\main.go

package main

import (
	"git.imooc.com/coding-447/category/common"
	"git.imooc.com/coding-447/category/domain/repository"
	service2 "git.imooc.com/coding-447/category/domain/service"
	"git.imooc.com/coding-447/category/handler"
	"github.com/jinzhu/gorm"
	"github.com/micro/go-micro/v2"
	log "github.com/micro/go-micro/v2/logger"
	"github.com/micro/go-micro/v2/registry"
	"github.com/micro/go-plugins/registry/consul/v2"

	_ "github.com/jinzhu/gorm/dialects/mysql"

	category "git.imooc.com/coding-447/category/proto/category"
)

func main() {
	//配置中心
	consulConfig,err := common.GetConsulConfig("127.0.0.1",8500,"/micro/config")
	if err !=nil {
		log.Error(err)
	}
	//注册中心
	consulRegistry := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			"127.0.0.1:8500",
		}
	})

	// New Service
	service := micro.NewService(
		micro.Name("go.micro.service.category"),
		micro.Version("latest"),
		//这里设置地址和需要暴露的端口
		micro.Address("127.0.0.1:8082"),
		//添加consul 作为注册中心
		micro.Registry(consulRegistry),
	)

	//获取mysql配置,路径中不带前缀
	mysqlInfo := common.GetMysqlFromConsul(consulConfig,"mysql")

	//连接数据库
	db,err := gorm.Open("mysql",mysqlInfo.User+":"+mysqlInfo.Pwd+"@/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
	if err !=nil {
		log.Error(err)
	}
	defer db.Close()
	//禁止复表
	db.SingularTable(true)


	//rp := repository.NewCategoryRepository(db)
	//rp.InitTable()
	// Initialise service
	service.Init()

	categoryDataService := service2.NewCategoryDataService(repository.NewCategoryRepository(db))

	 err = category.RegisterCategoryHandler(service.Server(),&handler.Category{CategoryDataService:categoryDataService})
	 if  err != nil {
	 	log.Error(err)
	 }

	// Run service
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}


4-8 完善Consul配置 

D:\Workspace\Go\src\micro_practice\category\common\config.go

D:\Workspace\Go\src\micro_practice\category\common\mysql.go

D:\Workspace\Go\src\micro_practice\category\common\swap.go

consul  新建key/value

第5章 链路追踪观望台

5-1 jaeger 原理 

链路追踪作用与特性
链路追踪 jaeger 术语,原理,组件,安装
在代码中使用链路追踪jaeger

微服务链路追(jaeger)踪作用
它是用来监视和诊断基于微服务的分布式系统
用于服务依赖性分析,辅助性能优化

微服务链路追踪(jaeger)主要特性
高扩展性
原生支持 OpenTracing
可观察性

微服务链路追踪(jaeger)-术语 Span
Jaeger 中的逻辑工作单元
具有操作名称,操作的开始时间和持续时间
跨度可以嵌套并排序以建立因果关系模型

Operation name:操作名称(也可以称作 Span name

Start timestamp:起始时间

Finish timestamp:结束时间

Span tag:一组键值对构成的Span 标签集合
Span log:一组Span 的日志集合
SpanContext:span 上下文对象

References( Span 间关系):相关的零个或者多个 Span

微服务链路追踪(jaeger)的五个重要组件
Jaeger-client (客户端库)
Agent(客户端代理)
Collector ( 数据收集处理)

Data Store (数据存储)
UI(数据查询与前端界面展示)

微服务链路追踪(jaeger)的安装
docker pull cap1573/jaeger
docker run -d --name jaeger -p 6831:6831/udp -p 16686:166861 cap1573/jaeger


5-2 商品领域 proto编写 

D:\Workspace\Go\src\micro_practice\product\proto\product\product.proto

syntax = "proto3";

package go.micro.service.product;

service Product {
	rpc AddProduct(ProductInfo) returns (ResponseProduct){}
	rpc FindProductByID(RequestID) returns (ProductInfo){}
	rpc UpdateProduct(ProductInfo) returns (Response) {}
	rpc DeleteProductByID(RequestID) returns (Response) {}
	rpc FindAllProduct(RequestAll) returns (AllProduct){}
}

message ProductInfo {
	int64 id = 1;
	string product_name = 2;
	string product_sku = 3;
	double product_price = 4;
	string product_description = 5;
	int64  product_category_id = 6;
	repeated ProductImage product_image = 7;
	repeated ProductSize product_size = 8;
	ProductSeo product_seo = 9;

}

message ProductImage {
	int64 id = 1;
	string image_name = 2;
	string image_code = 3;
	string image_url = 4;
}

message ProductSize{
	int64 id = 1;
	string size_name = 2;
	string size_code = 3;
}

message ProductSeo {
	int64 id = 1;
	string seo_title = 2;
	string seo_keywords = 3;
	string seo_description =4;
	string seo_code = 6;
}

message ResponseProduct {
	int64 product_id = 1;
}

message RequestID {
	int64 product_id = 1;
}

message Response {
	string msg = 1;
}

message RequestAll{

}

message AllProduct{
	repeated ProductInfo product_info =1;
}

D:\Workspace\Go\src\micro_practice\product\Makefile



.PHONY: proto
proto:
	sudo docker run --rm -v $(shell pwd):$(shell pwd) -w $(shell pwd) -e ICODE=CF388DF1EF1C5EBE cap1573/cap-protoc -I ./ --micro_out=./ --go_out=./ ./proto/product/product.proto

.PHONY: build
build: 

	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o product-service *.go

.PHONY: test
test:
	go test -v ./... -cover

.PHONY: docker
docker:
	docker build . -t product-service:latest

5-3 商品领域 模型编写

 D:\Workspace\Go\src\micro_practice\product\domain\model\product.go

D:\Workspace\Go\src\micro_practice\product\domain\model\product_size.go

D:\Workspace\Go\src\micro_practice\product\domain\model\product_seo.go

D:\Workspace\Go\src\micro_practice\product\domain\model\product_image.go


5-4 商品领域repository 开发

D:\Workspace\Go\src\micro_practice\product\domain\repository\product_repository.go


5-5 商品领域 service开发

D:\Workspace\Go\src\micro_practice\product\domain\service\product_data_service.go


5-6 商品领域 handler开发 

D:\Workspace\Go\src\micro_practice\product\handler\product.go


5-7 商品领域 链路追踪使用 

D:\Workspace\Go\src\micro_practice\product\common\config.go

D:\Workspace\Go\src\micro_practice\product\common\mysql.go

D:\Workspace\Go\src\micro_practice\product\common\swap.go

D:\Workspace\Go\src\micro_practice\product\common\jaeger.go

package common

import (
	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	"github.com/uber/jaeger-client-go/config"
	"io"
	"time"
)

//创建链路追踪实例
func NewTracer(serviceName string, addr string) (opentracing.Tracer, io.Closer, error) {
	cfg := &config.Configuration{
		ServiceName:serviceName,
		Sampler:&config.SamplerConfig{
			Type:                     jaeger.SamplerTypeConst,
			Param:                    1,
		},
		Reporter: &config.ReporterConfig{
			BufferFlushInterval:        1*time.Second,
			LogSpans:                   true,
			LocalAgentHostPort:         addr,
		},
	}
	return cfg.NewTracer()
}

D:\Workspace\Go\src\micro_practice\product\main.go

D:\Workspace\Go\src\micro_practice\product\productClient.go

package main

import (
	"context"
	"fmt"
	"git.imooc.com/coding-447/product/common"
	go_micro_service_product "git.imooc.com/coding-447/product/proto/product"
	"github.com/micro/go-micro/v2"
	"github.com/micro/go-micro/v2/registry"
	consul2 "github.com/micro/go-plugins/registry/consul/v2"
	opentracing2 "github.com/micro/go-plugins/wrapper/trace/opentracing/v2"
	"github.com/opentracing/opentracing-go"
	"log"
)

func main()  {
	//注册中心
	consul := consul2.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			"127.0.0.1:8500",
		}
	})
	//链路追踪
	t,io,err:=common.NewTracer("go.micro.service.product.client","localhost:6831")
	if err !=nil {
		log.Fatal(err)
	}
	defer io.Close()
	opentracing.SetGlobalTracer(t)

	service := micro.NewService(
		micro.Name("go.micro.service.product.client"),
		micro.Version("latest"),
		micro.Address("127.0.0.1:8085"),
		//添加注册中心
		micro.Registry(consul),
		//绑定链路追踪
		micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
		)

	productService:=go_micro_service_product.NewProductService("go.micro.service.product",service.Client())

	productAdd := &go_micro_service_product.ProductInfo{
		ProductName:        "imooc",
		ProductSku:         "cap",
		ProductPrice:       1.1,
		ProductDescription: "imooc-cap",
		ProductCategoryId:  1,
		ProductImage:       []*go_micro_service_product.ProductImage{
			{
				ImageName: "cap-image",
				ImageCode: "capimage01",
				ImageUrl:  "capimage01",
			},
			{
				ImageName: "cap-image02",
				ImageCode: "capimage02",
				ImageUrl:  "capimage02",
			},
		},
		ProductSize:        []*go_micro_service_product.ProductSize{
			{
				SizeName: "cap-size",
				SizeCode: "cap-size-code",
			},
		},
		ProductSeo:         &go_micro_service_product.ProductSeo{
			SeoTitle:       "cap-seo",
			SeoKeywords:    "cap-seo",
			SeoDescription: "cap-seo",
			SeoCode:        "cap-seo",
		},
	}
	response,err:=productService.AddProduct(context.TODO(),productAdd)
	if err !=nil {
		fmt.Println(err)
	}
	fmt.Println(response)
}

jager ui

find trace

链路追踪数据写入的过程中可以加入kafaka缓冲压力

可以通过链路追踪发现我们是否有循环调用

在链路中如非必要尽量避免带入异步场景的span

链路追踪还有哪些场景?
异步链路如何实现?
第6章 熔断,限流,负载均衡

6-1 熔断器作用和原理 
6-2 限流的作用和原理 
6-3 负载均衡作用和原理
6-4 微服务API网关 
6-5 server端 proto 文件编写
6-6 service 端 model 开发 
6-7 server端 repository 开发 
6-8 server端口service开发 
6-9 common 独立使用 
6-10 server端 handler开发 
6-11 server 端 添加限流 
6-12 购物车API层 添加熔断 
6-13 购物车API层 添加负载均衡 
6-14 API 网关及熔断看板使用 
第7章 性能监控能力完善

7-1 监控系统prometheus基本介绍 
7-2 docker-compose 基础介绍 
7-3 docker-compose 具体使用的例子 
7-4 订单领域 proto 开发 
7-5 订单领域 model 开发 
7-6 订单领域 repository 开发 
7-7 订单领域 service 开发 
7-8 微服务handler 代码编写 
7-9 订单main.go 添加 prometheus 监控 
7-10 监控系统可视化 
第8章 服务级观测台完成

8-1 日志系统ELK 架构介绍 
8-2 Filebeat 工作原理及注意事项 
8-3 Logstash 工作原理 
8-4 docker-compose 配置安装 ELK 
8-5 国际支付 PayPal 账户和沙盒环境指南 
8-6 日志zap 封装 
8-7 支付服务端 Proto 开发
8-8 支付信息 handler 开发 
8-9 支付服务端 main.go 文件开发
8-10 FileBeat 下载和使用说明 
8-11 支付API proto 开发 
8-12 国际支付PayPal handler 退款业务开发(上) 
8-13 国际支付PayPal handler 退款业务开发(下)
8-14 支付PayPal main.go 开发及效果展示(上) 
8-15 支付PayPal main.go 开发及效果展示(下)
8-16 幂等性介绍
8-17 Kibana日志可视化展示 
第9章 项目部署,完成闭环

9-1 k8s 基础入门及架构介绍 
9-2 k8s api server 架构及创建应用原理 
9-3 k8s 不同种类controller 作用讲解 
9-4 k8s 安装-阿里云创建ECS 
9-5 k8s 安装 服务器基础安装 
9-6 k8s 安装初始化Master 节点 
9-7 k8s node 节点加入集群 
9-8 kompose 介绍和说明 
9-9 kubectl 常用命令讲解 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/883171.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java之路--瓦解逻辑控制与方法使用已是瓮中捉鳖

嗨嗨大家!今天我们来学习逻辑运算和方法的使用~ 目录 一 逻辑控制 1 分支结构 1.1 if语句 1.2 switch 语句 2 循环结构 2.1 while 循环 2.2 for 循环 2.3 do while 循环 2.4 break 2.5 continue 3. 输出输入 二、方法的使用 1 方法定义语法 2 实参和…

苹果macOS 15.0 Sequoia正式版发布:iPhone应用镜像玩、手机消息电脑知

9月17日苹果向 Mac 电脑用户推送了 macOS 15 更新(内部版本号:24A335),除了引入数个 iOS 18 的新功能外,macOS 15 Sequoia 还带来了全新的 Continuity 功能 ——iPhone 镜像。 iPhone 镜像功能可以让用户直接在 Mac 上…

[Linux] Linux操作系统 进程的状态

标题:[Linux] Linux操作系统 进程的状态 个人主页:水墨不写bug (图片来源于网络) 目录 一、前置概念的理解 1.并行和并发 2.时间片 3.进程间具有独立性 4.等待的本质 正文开始: 在校的时候,你一定学过《…

图解Transformer就这30页PPT,你们真不看啊

图解Transformer就这30页PPT,你们真不看啊 主要介绍了Seq2Seq模型,慢慢引出了transformer的整体模型架构,比较具体的介绍了编码器部分的数据处理过程,包括了位置编码、多头注意力机制、残差连接、Layer Norm以及前馈网络等基本结…

支付宝沙箱环境 支付

一 什么是沙箱: 沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境 支付宝正式和沙箱环境的区别 : AI: 从沙箱到正式环境: 当应用程序开发完成后,需要将应用程序从沙箱环境迁移到正式环境。 这通常涉及…

如何查看线程

1、首先找到我们的电脑安装jdk的位置,这里给大家展示一下博主本人的电脑jdk路径下的jconsole位置。 2、 ok,那么找到这个jconsole程序我们直接双击打开就可以查看我们电脑的本地进程: jconsole 这里能够罗列出你系统上的 java 进程&#xff0…

古代经典名方目录数据库-支持经典名方检索!

"古代经典名方目录"是指一系列历史上流传下来的,被认为具有一定疗效的中药方剂的汇总。这些方剂多来源于历代医学典籍,经过长期临床实践的检验,部分已被收录于官方的目录之中,以便于现代医疗实践中的参考和应用。 目前…

手机在网状态查询接口如何用C#进行调用?

一、什么是手机在网状态查询接口? 手机在网状态查询接口是利用实时数据来对手机号码在运营商网络中的状态进行查询的工具,包括正常使用状态、停机状态、不在网状态、预销户状态等。 二、手机在网状态查询适用哪些场景? 例如:商…

设计模式-结构型-11-代理模式

文章目录 1. 基本介绍2. 静态代理2.1 基本介绍UML 类图 2.2 应用实例定义接口目标对象代理对象调用代理 2.3 静态代理优缺点 3. 动态代理3.1 基本介绍3.2 JDK 中生成代理对象的 API参数说明UML类图 3.3 应用实例定义接口目标对象代理工厂调用代理 4. Cglib 代理4.1 基本介绍4.2…

求一个数的因子数(c语言)

1.计算并输出给定整数n的所有因子(不包括1与n自身)之和。规定n的值不大于1000。(因子是能整除n的数 即n%i0) // 例如,在主函数中从键盘给n输入的值为856,则输出为: sum763。 2.第一步我们先输入n的数&…

Koa (下一代web框架) 【Node.js进阶】

koa (中文网) 是基于 Node.js 平台的下一代 web 开发框架,致力于成为应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石; 利用 async 函数 丢弃回调函数,并增强错误处理,koa 没有任何预置的中间件,可快速…

mysql安装教程(新手版)

本教程不需要手动设置配置文件,比较简单,适合新手,过程需联网。 1.找到mysql官网 mysql官网 一.mysql的安装 1.界面如下图,点击箭头所指。 2.选择mysql版本,系统,安装。 3.下载完成后双击打开&#xff0…

golang操作mysql利器-gorm

1、傻瓜示例 GORM通过将数据库表中的数据映射到面向对象的模型中,简化了数据库操作,使得开发者可以很方便的使用代码来操作数据库,而无需编写SQL语句。 目前有个mysql表:miniprogram_orders,其存储了所有用户对应的订…

Android SystemUI组件(07)锁屏KeyguardViewMediator分析

该系列文章总纲链接:专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明: 说明:本章节持续迭代之前章节的思维导图,主要关注左侧上方锁屏分析部分即可。 为了更好理解本文的内容,优先说明下SystemUI中与Ke…

CoreDNS实现跨集群service解析实践

CoreDNS实现跨集群service解析实践 背景介绍使用条件实现方案 CoreDNS是一款使用Go语言实现的专为云原生应用而生的DNS服务器。本文介绍CoreDNS在特定实际场景下的一种进阶使用实践,也许能为其他也在使用CoreDNS做服务发现的同学提供一些启发和思考。 背景介绍 在…

luceda ipkiss教程 76:设计光栅耦合器

案例分享:设计光栅耦合器 全部代码如下: from si_fab import all as pdk from ipkiss3 import all as i3 import numpy as npclass grating_coupler(i3.PCell):"""SOI grating coupler."""_name_prefix "grating_c…

mysql 05 InnoDB数据页结构

01.数据页结构的快速浏览 02.记录在页中的存储 在页的7个组成部分中,我们自己存储的记录会按照我们指定的 行格式 存储到 User Records 部分。但是在一开始生成页的时候,其实并没有 User Records 这个部分,每当我们插入一条记录&#xff0c…

单词记忆的化境:用思想的流水去淹没坚硬的石块

其实,鹅卵石通常都是很硬的。但是河底的石子,几乎大多都成了鹅卵石,它们被流水淹没,日复一日、夜以继日的冲刷着,没有了棱角。 在单词的记忆过程中,我们有太多的人,都有着不堪回首的往事&#x…

面试系列-携程暑期实习一面

Java 基础 1、Java 中有哪些常见的数据结构? 图片来源于:JavaGuide Java集合框架图 Java 中常见的数据结构包含了 List、Set、Map、Queue,在回答的时候,只要把经常使用的数据结构给说出来即可,不需要全部记住 如下&…

爬虫逆向学习(九):记录一个集cookie、请求参数、请求体、响应文本加密的站点反爬

此分享只用于学习用途,不作商业用途,若有冒犯,请联系处理 反爬前置信息 站点:aHR0cHM6Ly96d2Z3LmNxLmdvdi5jbi9pY2l0eS9pY2l0eS9lbmdpbmVlcmluZy9uYXZpZ2F0aW9u 接口:/icity/api-v2/cq.app.icity.engineering.Engine…