That's typically the way it's done, TCP or more likely HTTP/S checks of the application.
You could provide a URL / endpoint that always hits critical components and systems. For example it could
- Check it can reach the web server
- Web server reverse proxies to the app server
- App server test code that checks that a) the database is returning what it should, and b) that say your caching engine is working, and c) any integrated systems are responding appropriately.
If you don't check the full stack it's not a particularly effective health check.
You could read up on how AWS Elastic Load Balancer does health checks, which uses this technique.