In the development of the program we will assume that the external provided interface or data is not trustworthy. For example, the function is always to check the correctness of the parameters, in the unit test to the external interface provided by the shield off and so on. It's hard to make sure that you or someone else can provide an interface without any flaws. Since the interface is written by people, then there is a little bit of thinking about it, and when the interface is called, it is possible for an error or exception to occur. This discussion of the exception handling mechanism in Golang is actually the use of the two interfaces, panic and recover, similar to the try and catch in C + +.
1, Golang in the panic
Panic, Chinese explanation for panic. For example, when this statement appears in a single code, it is believed that all developers will panic when the product is online:
var MakecoreData *intnil *MakecoreData = 10000
If you don't do any processing, the Golang will appear if you run here.
errorornil0xc0000005 code=0x1 addr=0x0 pc=0x5d0676]
And then quit again, and the result is the same as the core in C + +.
Of course, this example may not make such a low-level error, but if the two statements with a copy of the logic, and the need for certain conditions to trigger, it may be difficult to find.
Take a look at the mechanism of panic in Golang, when the program is abnormal, Golang language level will throw a panic, in the above example, when the code runs to *makecoredata = 10000, will throw a panic, the function is over, If no processing is done, then the corresponding g in the program is abnormal, and the life cycle of the program ends. Similarly, if calling panic directly in your code is a consistent result. For example, call directly: Panic ("with a panic"), the result is:
Panic ("has a panic") and then displays the corresponding stack information.
The Recover
in
2,golang generates a panic when an exception occurs Golang. And a panic will always have a recover corresponding to it. When there is no processing, the behavior of the default recover behavior is to exit the process. Recover returns the return value of an error type, recording the exception. Because when an exception occurs, the function that produces the exception is no longer executed and exits immediately. That recover can only be called in defer, and is to be called in the defer statement before the exception is generated. Because in Golang, the corresponding function is inserted into the defer queue only when the defer statement is executed, and if the defer statement is called after the exception is generated, the defer corresponds to the function being executed because it is not inserted into the defer queue and is not called.
Here are a few examples to illustrate:
1) recover is not in defer:
import ( "fmt" "net/http" "runtime")func main() { ifrecovernil { fmt.Println(err) } var MakecoreData *intnil *MakecoreData = 10000 ifrecovernil { fmt.Println(err) } fmt.Println("hello world")}
From the code point of view, the code that generated the exception called recover, but from the results, the result of the operation is consistent with the non-recover.
2) Add a defer statement after the exception code, with recover in the statement, as in the following example:
import ( "fmt" "net/http" "runtime")func main() { var MakecoreData *intnil *MakecoreData = 10000 deferfunc() { ifrecovernil { fmt.Println(err) } }() fmt.Println("hello world")}
Judging from the results, it is consistent with the absence of recover.
3, add a defer statement before the exception, there is recover in the statement. Examples are as follows:
import ( "fmt" "net/http" "runtime")func main() { deferfunc() { ifrecovernil { fmt.Println(err) } }() var MakecoreData *intnil *MakecoreData = 10000 fmt.Println("hello world")}
The recover is actually executed in this code. This is one of the previous analyses. When an exception is encountered, the body of the function following the exception code will not be executed. function exits, this time executes the function registered in the defer queue, if there is recover operation here. Then the exception will be captured. Then the function exits without causing the program to end.
3, using the Golang exception mechanism to enhance the robustness of the code.
As can be seen from the Golang mechanism, exception handling recover preferably inserted into the corresponding defer queue at the entrance of the interface. This allows the program to provide services even when an exception occurs during an interface call. Take a Web service example to see how to use Golang's exception mechanism to enhance the robustness of your code:
1, Web services without any exception handling mechanisms are as follows:
import ( "FMT" "log" "net/http" ) func HelloServer (w http. Responsewriter, req *http. Request) {var makecoredata *int = nil *makecoredata = 10000 FMT. fprintf (W, "Hello World" )}func Main () {http. Handlefunc ( "/hello" , HelloServer) Err: = http. Listenandserve ( ": 12345" , nil ) if err! = nil {log. Fatal ( "Listenandserve:" , Err)}}
This code is obvious and an exception occurs when executing the business code. The cause of the exception is the same as described in the previous section. But if the service has multiple pages, not just/hello, when the client calls Localhost:12345/hello, a 404 return code is returned. But the service is not going to hang out. The reason is that Golang HTTP packet in the acceptance of a request will be at the entrance to the first call recover to ensure that the Golang development engineer in writing business code, if an exception occurs, not to cause the entire service to crash.
4, using Golang other functions with exception handling mechanism to enhance the robustness of the service.
With the exception mechanism of Golang, the service can still provide some temporary defect-free service in the case of defective. But this is not enough because they need to be repaired after the flaw is discovered and then redeployed after the modification.
For most services, the service needs to provide uninterrupted service 24*7. Then there is more to be done in the solution. Like what:
1, locate the anomaly point.
The location method can get stack information and the parameters and save it through the runtime package in Golang, and can know where the program is abnormal, so that it can be easily maintained later.
2, the use of primary and standby services
When a service is identified as defective, the primary and standby server upgrades can reduce the disruption caused by the update service.
3, service business module using hot-Plug plug-in
A business module is the code that runs the most in a service. In general, if there is an exception, at least 90% of it appears on the code of the Business module. If you take the form of a plugin, look at updating the module code without stopping the service.