当前位置:网站首页>I have used go language in the production environment for a month. I have four experiences

I have used go language in the production environment for a month. I have four experiences

2020-11-30 12:08:46 InfoQ

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" lately , I got a copy of DevOps Work , The work mainly involves the use of Go Write a new back-end system from scratch . before , I've never used... In a production environment Go, I've learned from personal projects ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" you ( Probably ) One should be used Web frame "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In limine , We decided to use only Go Of http Library and a simple routing Library ——"},{"type":"codeinline","content":[{"type":"text","text":"mux"}]},{"type":"text","text":"."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" However , I soon encountered production problems in real life :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" Recovery middleware "},{"type":"text","text":"—— Used for log printing and silent processing program code crash ."}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" journal "},{"type":"text","text":"—— I want a plan , You can print the information for each request , contain body params、auth tokens wait ( For debugging purposes )."}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" Better error handling "},{"type":"text","text":"—— I hope the error is still with error message and code JSON Respond to ."}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" Other commonly used Middleware "},{"type":"text","text":"—— contain JWT Verification and CORS."}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I have two choices : Solve the above problems by yourself , Use a different third-party library for each problem , Or choose one Web frame , Most of it has been done ( If not all ) These things ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I finally decided to use Echo This Web frame . It is reported that , It's in GitHub It's close 2 Ten thousand like , There's a very active community , And great documentation . I think it's a great tool to do the job ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/23\/cc\/23ce53db89926a4ec71c7e0cfea8cccc.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I also found , use "},{"type":"codeinline","content":[{"type":"text","text":"echo"}]},{"type":"text","text":" There are some simpler templates for writing applications ( Mainly parsing json body、 To write errors And manual settings headers etc. ), Make the code more readable ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/d7\/ae\/d738630299bde59f7f54e84e5799faae.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" However , When you have some more complex endpoints , You'll notice the real difference in productivity . You will often come across something that needs to be verified JSON Fields , And we need meaningful error information to describe the error . If you want to do this without using any libraries , Your code will soon become difficult to read :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/48\/61\/486024d41cff85ab4f78d0fb23416a61.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" You need a good code structure "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Go Of Web frame ( Or general go project ) No specific file structure is enforced . If you have ASP.NET\/ASP.NET Core Things like that , When I say that some frameworks are tightly structured , And a lot of things are done by convention rather than by explicit specification , You'll know what I'm talking about ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" About Go The problem is , It's easy to skip learning about building code structures , Makes code hard to read and maintain . If you don't know what I'm talking about , Here's one I wrote a while ago ("},{"type":"text","marks":[{"type":"strong"}],"text":" Perishing "},{"type":"text","text":")Go Endpoint example :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/b9\/86\/b98603e588e67a3d936ab02f4fab3a86.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Do you know what I mean? ? Added all the "},{"type":"codeinline","content":[{"type":"text","text":"CreateUser"}]},{"type":"text","text":" and "},{"type":"codeinline","content":[{"type":"text","text":"CreateAgency"}]},{"type":"text","text":" After the method ,“ better ” Methods are likely to contain more lines , however ... It will be very easy to understand later 、 reusing 、 Debug and modify , Because each method has a separate purpose . If you don't understand , I strongly recommend that you take a look at the following resources on good code structure :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/github.com\/ribice\/gorsk","title":"","type":null},"content":[{"type":"text","text":"https:\/\/github.com\/ribice\/gorsk"}]},{"type":"text","text":"-  Basics REST API A good example of "}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/github.com\/bxcodec\/go-clean-arch","title":"","type":null},"content":[{"type":"text","text":"https:\/\/github.com\/bxcodec\/go-clean-arch"}]},{"type":"text","text":"-  Also a REST API Example , But follow it more strictly “Clean Architecture” idea "}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Generally speaking , The idea is simple . You should separate the code that communicates with the database from the actual application logic itself , And application logic should also be related to transmission \/ Endpoint logic ( In this case, it's HTTP Endpoint ) Separate ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Choose your SQL driver"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" When I first used Go When you start programming , I want to use the latest library as much as possible , So I chose to use "},{"type":"codeinline","content":[{"type":"text","text":"database\/sql"}]},{"type":"text","text":" package ( Use Postgres). Although the experience can be , But when it comes to querying data , I came across a lot of samples , Especially if you have to use Scan grammar . This leads me to the following 2 An option :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"sqlx"}]},{"type":"text","text":"- One is based on "},{"type":"codeinline","content":[{"type":"text","text":"database\/sql"}]},{"type":"text","text":" Light weight wrapper for , Made some extensions , Make it easier to make queries ."}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"gorm"}]},{"type":"text","text":"- One for Go Of ORM(Object-Relational Mapping, object - Relation mapping ) library , According to your Go models Generate SQL models And query ."}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I don't think there is a clear “ better ” library , Ultimately, it depends on the usage scenarios and personal preferences ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"gorm"}]},{"type":"text","text":" It might make you a little easier , Especially if you often forget to add fields to the query after modifying the database ( Because in gorm in , You don't have to do this at all )."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" On the other hand ,"},{"type":"codeinline","content":[{"type":"text","text":"sqlx"}]},{"type":"text","text":" More so SQL Centered , It's more like writing Go Code to call SQL Interface , instead of gorm According to the plan Go Code generation SQL. If you like total control SQL And you don't have to learn GORM New syntax , So this is a good plan ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Docker"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" One of the challenges I encountered was to configure the production environment for this project . There are always some differences between the development environment and the production environment , For example, which port is the application running on 、 The host and credentials of the database , wait ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I've seen people pass through JSON、YAML even to the extent that git Neglected .go File to configure application variables . I personally found that env It's better to use the document , Especially with docker-compose Use :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/70\/73\/708b9f588yyc8e83ff9645f380174d73.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/96\/3a\/96386e0a7212141a4bcb5fccb59af63a.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I usually use these in combination with the following practical functions :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/47\/41\/47613e382533632c1039c66fa4983f41.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" use Go structure Docker The mirror is also super simple :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/62\/11\/62b7f3cb7f7b35b972d58b0b82504e11.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Other ?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I also thought of something else , But I don't think they deserve to be discussed in separate chapters :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/tour.golang.org\/basics\/7","title":"","type":null},"content":[{"type":"text","text":"Named returns in Go"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/golang.org\/doc\/effective_go.html","title":"","type":null},"content":[{"type":"text","text":"Effective Go"}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/blog.golang.org\/using-go-modules","title":"","type":null},"content":[{"type":"text","text":"Go Modules"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Link to the original text :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/tdom.dev\/go-in-production","title":"","type":null},"content":[{"type":"text","text":"https:\/\/tdom.dev\/go-in-production"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/11/20201130120838577a.html

随机推荐